4

我创建了一个 Servlet 3.0 Web 片段 jar,其中包含一个文件:

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

应用程序启动时 Web 片段启用的 Servlet 上下文侦听器之一执行以下代码:

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

这意味着i18n.properties如果最终用户未在其 Web 应用程序的同一路径中指定自己的文件,则应使用 Web 片段的上述文件。

这适用于 Tomcat 7,但不适用于 Jetty 8。这是在 Jetty 8 中部署时产生的异常:

java.util.MissingResourceException:找不到基本名称 com.foo.whatever.i18n 的包,语言环境 en_US

有没有办法让 Jetty 8 尊重 web 片段的类路径贡献?

4

1 回答 1

6

Servlet 规范中没有任何内容表明 WEB-INF/lib 中的 jar 文件可以通过此方法将类贡献给类路径。规范讨论了 WEB-INF/lib 中的 jar 文件能够通过其 META-INF/resources 目录提供静态内容。例如,参见第 4.6 节“资源”第 4-41 页;第 8.2.3 节“从 web.xml、web-fragment.xml 和注释组装描述符”点 2.5.g.xi pg 8-81;第 10.5 节“目录结构”第 10-104 页;第 10.10 节“欢迎文件”第 10-112 页;第 A.3 节“自 Servlet 3.0 公开审查以来的更改”点 4 pg A-202。

在规范的其他地方,它指的是“the”(即单数)WEB-INF 和 WEB-INF/classes 目录。

规范中没有说明如何将 META-INF/resources/WEB-INF/ 目录与主 webapp 中的现有 WEB-INF/ 目录合并(即主 WEB-INF/classes 目录中的类是否应该覆盖类META-INF/resources/WEB-INF/classes 目录中的同名或包?反之亦然?)。然而,正如我之前所引用的,在 META-INF/resources 中有关于如何处理资源的明确说明。

另请注意,规范允许 META-INF/web-fragment.xmls 通过该机制被忽略,但这不会影响类加载:将不会检查被忽略的片段 jar 的注释,也不会调用其任何 ServletContainerInitializers,但是它的类将始终在类路径上。

所以简而言之,这似乎是特定于 tomcat 的行为。为了可靠地获取您的属性文件,您需要将其放入 WEB-INF/lib jar 中的正常位置。您不能使用 Servlet Spec web-fragment.xml 机制来控制该属性文件是否可见。

问候简

于 2015-01-22T16:01:48.027 回答