我正在运行嵌入式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();
}
请注意,文件确实存在,尽管我怀疑它与码头扫描tlds的方式有关(请注意,此应用程序根本不使用JSP)。
答案 0 :(得分:1)
在从Jetty 6.x升级到Jetty 9.x的同时,您还升级了Servlet支持版本。
从Servlet 2.5(在Jetty 6中)到Servlet 3.1(在Jetty 9中)。
这意味着在启动Web应用程序时,容器现在有更多工作要做。
目前影响您的一个因素是Servlet 3.0中引入了javax.servlet.ServletContainerInitializer
。
Jetty 9.x中存在许多ServletContainerInitializer
(SCI)实现,每个实现都可以声明一个可选的@HandlesTypes
,该列表将列出SCI感兴趣的注释和/或类的种类。已在ServletContainerInitializer.onStartup(Set<Class<?>> c, ServletContext ctx)
中收到通知。这意味着在启动时,Jetty必须扫描webapp容器类(WEB-INF/classes
和WEB-INF/lib/*.jar
)和服务器容器jar(服务器ClassLoader),以查找已声明的@HandlesTypes
的所有匹配类。 / p>
此扫描是Servlet 3.0的要求。
简而言之,如果WEB-INF/lib
中也有jar文件,则无法阻止WAR文件的扩展,因为Java不支持jar文件的嵌套解压缩。换句话说,您不能使用JarFile
来遍历另一个JAR文件中的JAR文件。 (堆栈跟踪中的JarURLConnection
是由于调用JarURLConnection.getJarFile()
而引起的,该调用允许遍历JAR文件内容,这是对JAR进行正确字节码扫描所必需的)
替代选项:快速入门...
您可以选择使用Jetty quickstart并在生成时预先计算扫描,然后使用生成的快速入门而不是在运行时扫描内容,将其嵌入您的war文件中。