我有一个嵌入式Jetty运行,最近不得不升级到版本9.4.16.v20190411,但WAR文件不再部署,并显示以下错误消息:
2019-04-17 11:37:13.054:WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.w.WebAppContext@657c8ad9{root,/,jar:file:///D:/SLX/Agent/webapps/root.war!/,UNAVAILABLE}{D:\SLX\Agent\webapps\root.war}
java.io.FileNotFoundException: JAR entry WEB-INF/lib/FastInfoset-1.2.15.jar!/ not found in D:\SLX\Agent\webapps\root.war
at java.base/sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:147)
at java.base/sun.net.www.protocol.jar.JarURLConnection.getJarFile(JarURLConnection.java:92)
at org.eclipse.jetty.webapp.MetaInfConfiguration.getTlds(MetaInfConfiguration.java:438)
at org.eclipse.jetty.webapp.MetaInfConfiguration.scanForTlds(MetaInfConfiguration.java:355)
at org.eclipse.jetty.webapp.MetaInfConfiguration.scanJars(MetaInfConfiguration.java:173)
at org.eclipse.jetty.webapp.MetaInfConfiguration.preConfigure(MetaInfConfiguration.java:107)
at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:506)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:544)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:119)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
at org.eclipse.jetty.server.Server.start(Server.java:418)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:382)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at com.linxberg.timelogix.service.App.main(App.java:49)
我正在使用嵌入式Web服务器的以下启动代码:
public static void main( String[] args ) throws Exception
{
File loc = findWebappsDir();
if (loc == null)
throw new FileNotFoundException("Could not find webapps directory.");
DeploymentManager dm = new DeploymentManager();
WebAppProvider wap = new WebAppProvider();
//prefer THIS loader over child loaders, the opposite of
//what J2EE specs, but that doesn't allow our configuration overrides to work correctly
wap.setParentLoaderPriority(true);
wap.setMonitoredDirectories(List.of(loc.getAbsolutePath()));
wap.setScanInterval(30);
dm.addAppProvider(wap);
ContextHandlerCollection chc = new ContextHandlerCollection();
server = new Server(8080);
dm.setContexts(chc);
server.addBean(dm);
server.setHandler(chc);
server.start();
}
请注意,该文件确实存在,但我怀疑它与jetty扫描tlds的方式有关(请注意,此应用程序根本不使用JSP)。
在升级到Jetty 9.x(来自Jetty 6.x)时,您还升级了Servlet支持版本。
从Servlet 2.5(在Jetty 6中)到Servlet 3.1(在Jetty 9中)。
这意味着当启动webapp时,容器现在有更多的事情要做。
现在影响你的是引入javax.servlet.ServletContainerInitializer
(在Servlet 3.0中)。
Jetty 9.x中有许多ServletContainerInitializer
(SCI)实现,每个实现可以声明一个可选的@HandlesTypes
,它将列出SCI有兴趣在ServletContainerInitializer.onStartup(Set<Class<?>> c, ServletContext ctx)
中被通知的注释和/或类的类型。这意味着在启动时,Jetty必须扫描webapp容器类(WEB-INF/classes
和WEB-INF/lib/*.jar
)和Server Container jar(Server ClassLoader)以查找声明的@HandlesTypes
的任何和所有匹配类。
此扫描是Servlet 3.0的要求。
简而言之,如果您在WEB-INF/lib
中也有jar文件,则无法阻止扩展WAR文件,因为Java不支持jar文件的嵌套解压缩。换句话说,你不能使用JarFile
来处理另一个JAR文件中的JAR文件。 (堆栈跟踪中的JarURLConnection
是由于调用JarURLConnection.getJarFile()
,它允许遍历JAR文件内容,正确的字节码扫描JAR所需)
另一种选择:快速入门......
您可以选择使用Jetty quickstart并在构建时预先计算扫描并将其嵌入到war文件中,使用生成的快速入门而不是在运行时扫描内容。