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

1

5

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?

Dresden answered 21/1, 2015 at 23:36 Comment(1)
That Tomcat does allow this by default is a bug. That bug will be fixed in the next release. If you need this feature then it should be possible to restore equivalent behaviour with Tomcat specific configuration.Rhynchocephalian
T
7

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

Tugman answered 22/1, 2015 at 16:1 Comment(1)
Excellent answer Jan - thank you! I did indeed place the file in the jar's 'normal' classpath location, i.e. my-plugin.jar:com/foo/whatever/i18n.properties and things work as expected in Tomcat and Jetty (and I hope, presumably in other containers as well).Dresden

© 2022 - 2024 — McMap. All rights reserved.