无法在jetty 9.4.16.v20190411中部署WAR:在WEB-INF / lib下的战争中接收jar的FileNotFoundException

问题描述 投票:0回答:1

我有一个嵌入式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)。

java embedded-jetty
1个回答
1
投票

在升级到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/classesWEB-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文件中,使用生成的快速入门而不是在运行时扫描内容。

© www.soinside.com 2019 - 2024. All rights reserved.