Невозможно развернуть WAR на пристани 9.4.16.v20190411: получено исключение FileNotFoundException для jar, находящегося в состоянии войны, под WEB-INF / lib - PullRequest
0 голосов
/ 17 апреля 2019

У меня работает встроенная 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)

Я использую следующеекод запуска для встроенного веб-сервера:

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 ввсе).

1 Ответ

1 голос
/ 17 апреля 2019

При обновлении до Jetty 9.x (с Jetty 6.x) вы также обновили версию поддержки сервлета.

От Servlet 2.5 (в Jetty 6) до Servlet 3.1 (в Jetty 9).

Это означает, что в контейнере теперь есть что делать при запуске веб-приложения.

На вас сейчас воздействует введение javax.servlet.ServletContainerInitializer (в Servlet 3.0).

Существует множество реализаций ServletContainerInitializer (SCI), представленных в Jetty 9.x, каждая из которых может объявить необязательный @HandlesTypes, который будет перечислять, какие виды аннотаций и / или классов интересует SCI. в уведомлении о ServletContainerInitializer.onStartup(Set<Class<?>> c, ServletContext ctx). Это означает, что при запуске Jetty должен сканировать классы контейнеров веб-приложения (WEB-INF/classes и WEB-INF/lib/*.jar) и jar-контейнеры сервера (Server ClassLoader), чтобы найти все подходящие классы для объявленного @HandlesTypes.

Это сканирование является требованием Servlet 3.0.

Короче говоря, вы не можете предотвратить расширение файла WAR, если у вас также есть файлы jar в WEB-INF/lib, так как Java не поддерживает вложенную распаковку файла jar. Иными словами, вы не можете использовать JarFile для обхода файла JAR, который находится в другом файле JAR. (JarURLConnection в вашей трассировке стека вызвано вызовом JarURLConnection.getJarFile(), который позволяет просматривать содержимое файла JAR, необходимое для правильного сканирования байт-кода JAR)

Альтернативный вариант: QuickStart ...

Вы можете использовать быстрый запуск Jetty , предварительно рассчитать сканирование во время сборки и встроить его в файлы war, используя этот сгенерированный быстрый запуск вместо сканирования контента во время выполнения.

...