Bug 57155 - Allow Context without real docbase in embedded Tomcat
Summary: Allow Context without real docbase in embedded Tomcat
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.0.x-trunk
Hardware: PC All
: P2 enhancement (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2014-10-28 00:44 UTC by Konstantin Kolinko
Modified: 2014-10-29 22:21 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description Konstantin Kolinko 2014-10-28 00:44:09 UTC
Many of Tomcat test cases do the following to create and configure a web application programmatically:

        // Must have a real docBase - just use temp
        Context ctx =
            tomcat.addContext("", System.getProperty("java.io.tmpdir"));

Essentially, it makes Tomcat to serve the contents of the system temporary directory. Sometimes it results in failures on CI servers (bug 57154 is an example).

There shall be a way to configure a context that does not need a real docbase.

I do not see a use case for that when running a standalone Tomcat, because docbase is needed to provide executable code for the application, but I do see the use case when running embedded Tomcat. In embedded Tomcat the entire web application can be configured programmatically.

If I use a non-existent docbase, e.g.

        Context ctx = 
            tomcat.addContext("", "ROOT");

Tomcat startup fails with

Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	... 6 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.webresources.StandardRoot@123f26]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:4875)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5004)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 6 more
Caused by: java.lang.IllegalArgumentException: The main resource set specified [(censored)\test-tmp\webapps\ROOT] is not valid
	at org.apache.catalina.webresources.StandardRoot.startInternal(StandardRoot.java:665)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 9 more

If I do the following:

        Context ctx =
            tomcat.addContext("", "");

the test passes successfully. Apparently it is using docBase = appBase. An odd configuration, but it works if there are no other web applications in appBase.
Comment 1 Konstantin Kolinko 2014-10-28 01:03:32 UTC
I think that docBase that is equal to the empty string can be treated specially as this "No doc base" case. I mean that in this case one needs to configure the resources (org.apache.catalina.webresources.StandardRoot) so that no files are served.

I think that now there is a risk that somebody will be unwillingly serving files from appbase if one specifies <Context docBase=""/> . If anybody really wants to serve files from appbase directory, one can use "." or an absolute path.

Alternatively, add one-argument method to Tomcat class as
 public Context addContext(String contextPath)
and perform all configuration of StandardRoot programmatically. In this case we can avoid special processing of docBase="".
Comment 2 Mark Thomas 2014-10-29 15:52:00 UTC
I'm leaning towards treating a docBase value of "" as invalid and using null to signal that a docBase on the file system is not required. I need to do some testing of this.
Comment 3 Konstantin Kolinko 2014-10-29 18:30:10 UTC
I envision a caveat with ContextConfig.fixDocBase().
The fixDocBase() method replaces null docBase with one calculated from path, (new ContextName(path, context.getWebappVersion())).getBaseName().

Using null in tomcat.addContext(path, null) is indeed a good API. (Maybe add a single-argument Tomcat.addContext(path) for this use case).
Comment 4 Mark Thomas 2014-10-29 22:21:37 UTC
I don't see a need to change ContextConfig. That is not intended for use in embedding. If it was used it would only be used when there was a docBase on the filesystem.

This has been fixed in 8.0.x for 8.0.15 onwards.