无法在码头9.4.16.v20190411中部署WAR:接收在WEB-INF / lib下处于战争状态的jar的FileNotFoundException

时间:2019-04-17 18:11:55

标签: java embedded-jetty

我正在运行嵌入式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)。

1 个答案:

答案 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/classesWEB-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文件中。