jettyservlet-3.0web-infjetty-8web-fragment

Jetty 8: can a web fragment jar's /META-INF/resources/WEB-INF/classes directory contribute to the web app's classpath?


I created a Servlet 3.0 web fragment jar that contains a file:

/META-INF/resources/WEB-INF/classes/com/foo/whatever/i18n.properties

One of the Servlet Context Listeners enabled by the web fragment at app startup executes the following code:

public static final String BUNDLE_BASE_NAME = "com.foo.whatever.i18n";
//... later:
ResourceBundle.getBundle(BUNDLE_BASE_NAME, locale);

This implies that the web fragment's above i18n.properties file should be used if the end-user does not specify their own at that same path in their web application.

This works in Tomcat 7, but not in Jetty 8. This is the resulting exception when deploying in Jetty 8:

java.util.MissingResourceException: Can't find bundle for base name com.foo.whatever.i18n, locale en_US

Is there a way to get Jetty 8 to honor the web fragment's classpath contribution?


Solution

  • There's nothing in the Servlet Spec that indicates that a jar file inside WEB-INF/lib can contribute classes to the classpath via this method. The Spec talks about jar files in WEB-INF/lib being able to contribute static content via their META-INF/resources directory. Eg see Section 4.6 "Resources" pg 4-41; Section 8.2.3 "Assembling the descriptor from web.xml, web-fragment.xml and annotations" point 2.5.g.xi pg 8-81; Section 10.5 "Directory Structure" pg 10-104; Section 10.10 "Welcome Files" pg 10-112; Section A.3 "Changes since Servlet 3.0 Public Review" point 4 pg A-202.

    In other places in the Spec it refers to "the" (ie singular) WEB-INF and WEB-INF/classes directories.

    There are no instructions in the Spec for how to merge a META-INF/resources/WEB-INF/ directory with an existing WEB-INF/ dir from the main webapp (ie should classes in the main WEB-INF/classes dir override classes of the same name or package in a META-INF/resources/WEB-INF/classes dir? Or vice-versa?). Whereas, there are explicit instructions for what to do with resources in META-INF/resources, as I've previously cited.

    Note also that the Spec allows for META-INF/web-fragment.xmls to be ignored via the mechanism, but this does NOT affect classloading: an ignored fragment jar will not be inspected for annotations and will not have any of its ServletContainerInitializers called, however its classes will always be on the classpath.

    So in short this seems to be tomcat-specific behaviour. To reliably have your properties file picked up, you would need to put it into the normal place in a WEB-INF/lib jar. You cannot use the Servlet Spec web-fragment.xml mechanism to control whether or not that properties file is visible.

    regards Jan