我如何在 Jetty 9.4 中使用 Spring WebApplicationInitializer?

How do I use a Spring WebApplicationInitializer in Jetty 9.4?

我们有一个 Java 应用程序,它在 Jetty 9.2 上使用 Spring WebApplicationInitializer 加载:

2019-07-11 09:52:18.464:INFO:oejs.Server:main: jetty-9.2.17.v20160517
2019-07-11 09:52:18.487:INFO:oejs.AbstractNCSARequestLog:main: Opened /apps/jetty/servers/erti/logs/2019_07_10.request.log
2019-07-11 09:52:18.491:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/apps/jetty/servers/erti/contexts/] at interval 1
2019-07-11 09:52:18.522:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@446e7065{/hb,null,AVAILABLE}
2019-07-11 09:52:25.437:INFO:/services/information-requests:main: 1 Spring WebApplicationInitializers detected on classpath
2019-07-11 09:52:26.694:INFO:/services/information-requests:main: Initializing Spring root WebApplicationContext

但是,如果我们更新到 Jetty 9.4,WebApplicationInitializer 不会被拾取,并且每个页面都会收到 404(尽管静态资产仍然可见):

2019-07-11 09:55:22.915:WARN:oejx.XmlConfiguration:main: Property 'jetty.deploy.monitoredDirName' is deprecated, value from 'jetty.deploy.monitoredDir' used
2019-07-11 09:55:22.956:WARN:oejx.XmlConfiguration:main: Property 'jetty.port' is deprecated, value from 'jetty.http.port' used
2019-07-11 09:55:22.988:WARN:oejx.XmlConfiguration:main: Property 'jetty.keystore.password' is deprecated, use 'jetty.sslContext.keyStorePassword' instead
2019-07-11 09:55:22.990:WARN:oejx.XmlConfiguration:main: Property 'jetty.keymanager.password' is deprecated, use 'jetty.sslContext.keyManagerPassword' instead
2019-07-11 09:55:22.990:WARN:oejx.XmlConfiguration:main: Property 'jetty.truststore.password' is deprecated, use 'jetty.sslContext.trustStorePassword' instead
2019-07-11 09:55:23.069:INFO:oejs.Server:main: jetty-9.4.11.v20180605; built: 2018-06-05T18:24:03.829Z; git: d5fc0523cfa96bfebfbda19606cad384d772f04c; jvm 1.8.0_172-b11
2019-07-11 09:55:23.089:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///apps/jetty/servers/erti/contexts/] at interval 1
2019-07-11 09:55:23.131:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@191c6e13{/hb,null,AVAILABLE}

是否需要启用特定的 Jetty 模块才能获取 ServletContainerInitializer 个实例?我的印象是 ServletContainerInitializer 自 Servlet 3.0 以来就非常标准,而 Jetty 9.4 使用 3.1。或者为了让 Spring 容器初始化程序检测到我们的 WebApplicationInitializer,可能还需要其他东西?

Jetty 9.4 报告如下:

Enabled Modules:
================
    0) mail            transitive provider of mail for jndi
    1) resources       ${jetty.base}/start.d/start.ini
    2) threadpool      transitive provider of threadpool for server
                       init template available with --add-to-start=threadpool
    3) server          transitive provider of server for http
                       transitive provider of server for plus
                       transitive provider of server for ssl
                       transitive provider of server for security
                       transitive provider of server for servlet
                       transitive provider of server for requestlog
                       transitive provider of server for jndi
                       init template available with --add-to-start=server
    4) jndi            transitive provider of jndi for plus
    5) security        transitive provider of security for webapp
                       transitive provider of security for plus
    6) transactions    transitive provider of transactions for plus
    7) servlet         transitive provider of servlet for webapp
                       transitive provider of servlet for jsp
    8) webapp          transitive provider of webapp for plus
                       transitive provider of webapp for deploy
                       init template available with --add-to-start=webapp
    9) plus            transitive provider of plus for annotations
   10) annotations     ${jetty.base}/start.d/start.ini
   11) apache-jsp      transitive provider of apache-jsp for jsp
   12) console-capture ${jetty.base}/start.d/start.ini
   13) deploy          ${jetty.base}/start.d/start.ini
   14) http            ${jetty.base}/start.d/start.ini
   15) ssl             transitive provider of ssl for https
                       init template available with --add-to-start=ssl
   16) https           ${jetty.base}/start.d/start.ini
   17) jsp             ${jetty.base}/start.d/start.ini
   18) requestlog      ${jetty.base}/start.d/start.ini

并且我们的应用程序正在使用 Jetty 上下文文件进行部署:

<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/services/information-requests</Set>
  <Set name="war"><Property name="jetty.base" default="."/>/webapps/erti.war</Set>
  <Set name="extraClasspath">/apps/config/erti/</Set>
  <!-- Turn off JSESSIONID appearing in URL-->
  <Call name="setInitParameter">
    <Arg>org.eclipse.jetty.servlet.SessionIdPathParameterName</Arg>
    <Arg>none</Arg>
  </Call>
</Configure>

我发现了问题。我们的 web.xml 还没有更新,仍然配置了 2.4 的 webapp 版本。 Jetty 的行为在 https://github.com/eclipse/jetty.project/issues/1466 中发生了变化,因此它不再寻找 ServletContainerInitializer 低于 2.5 的 webapp 版本。