JavaDoc for Tomcat.addWebApp(String contextPath, String docBase) says docBase is relative to the server home: * @param docBase Base directory for the context, for static files. Must * exist, relative to the server home However, docBase is eventually passed as the first argument to getWebappConfigFile(String path, String contextName) where it is evaluated as if it were an absolute path: protected URL getWebappConfigFile(String path, String contextName) { File docBase = new File(path); if (docBase.isDirectory()) { The docBase.isDirectory() check will fail when docBase is a relative path, and then we incorrectly end up calling getWebappConfigFileFromWar(). Except for loading the context.xml file, everything else "works" when a relative path is used, so I assume this is a bug in the implementation and not the JavaDoc?
Looking at the history of that file, the docBase was always meant to be absolute. Saying it could be relative is a Javadoc bug added (by me) as part of the fix for bug 57723. I'll get the Javadoc corrected. I did look at the possibility of supporting a relative path but that begs the question "Relative to what?". CATALINA_BASE isn't an option as that is (usually) created dynamically when using the Tomcat class. Using current directory is too fragile for my liking.
Fixed in: - 11.0.x for 11.0.0-M5 onwards - 10.1.x for 10.1.8 onwards - 9.0.x for 9.0.74 onwards - 8.5.x for 8.5.88 onwards
(In reply to Mark Thomas from comment #1) > I did look at the possibility of supporting a relative path but that begs > the question "Relative to what?". CATALINA_BASE isn't an option as that is > (usually) created dynamically when using the Tomcat class. Funny enough, I actually discovered the issue when specifying a fixed CATALINA_BASE (setting server.tomcat.basedir with Spring Boot). For example, if CATALINA_BASE=/foo and /foo/webapps/bar exists, then addWebApp("/bar", "bar") actually works just fine. The only issue that appeared was NoSuchFileException stemming from getWebappConfigFile interpreting "bar" as absolute when trying to locate context.xml as I mentioned in the original post. Otherwise, the app works (as I have no context.xml anyway). I think this works because of the underlying Context object, which says this for setDocBase(String): > Set the document root for this Context. This can be either an absolute pathname or > a relative pathname. Relative pathnames are relative to the containing Host's appBase. So I guess "Relative to what?" is sort of explained? But anyway, using an absolute path is easy enough for me. Plus it has the added benefit I hadn't considered until now, that you can load from any path and it doesn't need to be underneath an existing CATALINA_BASE. Thank you for clearing this up.