启用Jetty 9.3.9.v20160517在启用注释时找不到提供程序WebSocketCdiInitializer

时间:2016-06-06 13:37:38

标签: java jetty jetty-9

使用DeploymentManager部署webapp时,会抛出此错误

2016-06-06 15:19:37,750 WARN  [org.eclipse.jetty.deploy.DeploymentManager] (WrapperSimpleAppMain) Unable to reach node goal: started (DeploymentManager.java:506)
java.util.ServiceConfigurationError: javax.servlet.ServletContainerInitializer: Provider org.eclipse.jetty.cdi.websocket.WebSocketCdiInitializer not found
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:372)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.eclipse.jetty.annotations.AnnotationConfiguration.getNonExcludedInitializers(AnnotationConfiguration.java:864)
    at org.eclipse.jetty.annotations.AnnotationConfiguration.configure(AnnotationConfiguration.java:444)
    at org.eclipse.jetty.webapp.WebAppContext.configure(WebAppContext.java:494)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1361)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:772)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:520)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)

使用以下方法启用注释支持时会发生这种情况:

    org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
    classlist.addBefore(
        "org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
        "org.eclipse.jetty.annotations.AnnotationConfiguration"
    );
    classlist.addAfter(
        "org.eclipse.jetty.webapp.FragmentConfiguration",
        "org.eclipse.jetty.plus.webapp.PlusConfiguration"
    );

jar cdi-websocket-9.3.9.v20160517.jar位于类路径

这个issue建议停用cdi Jetty模块,但它没有说明如何使用嵌入式Jetty。

我该如何解决这个问题?

修改

我们意识到此问题可能是由运行应用程序的(复杂)环境引起的。

因此,我特别感兴趣的是理解什么可能导致抛出此异常的根本原因

结论

TD; LR:Jetty-9.3.9 embedded!= Jetty-9.3.9 standalone

使用Jetty 9.2.14,我们以编程方式启动了jetty(就像Jetty嵌入式),但是使用了独立Jetty的无包装版本的jar。

自从Jetty 7(或者甚至是6)以来,我们已经让这个设置工作正常,但升级到Jetty 9.3.9时事情开始破裂。

注意:我们使用的是Jersey,servlet和一些JSP。没有websockets。我们正在升级到测试HTTP / 2。

2 个答案:

答案 0 :(得分:1)

从Jetty 9.3.2的源代码[1] (我想在进入9.3.9之后行没有改变)我找到了以下源代码片段:

851         //Get initial set of SCIs that aren't from excluded jars or excluded by the containerExclusionPattern, or excluded
852         //because containerInitializerOrdering omits it
853         for (ServletContainerInitializer sci:loadedInitializers)
854         {       
855             if (matchesExclusionPattern(sci)) 
856             {
857                 if (LOG.isDebugEnabled()) LOG.debug("{} excluded by pattern", sci);
858                 continue;
859             }
860             
861             Resource sciResource = getJarFor(sci);
862             if (isFromExcludedJar(context, sci, sciResource)) 
863             { 
864                 if (LOG.isDebugEnabled()) LOG.debug("{} is from excluded jar", sci);
865                 continue;
866             }

评论告诉SCI(ServletContainerInitializer)在这里检查是否因任何原因被排除。你的stacktrace告诉我们第864行正在抛出异常。 LOG.debug试图告诉原因是SCI 来自排除的jar 因此导致你遇到的错误。

我的建议是检查你的maven配置(你的pom.xml)有关包含 org.eclipse.jetty.annotations.AnnotationConfiguration 文件的软件包:

<!-- http://mvnrepository.com/artifact/org.eclipse.jetty/jetty-annotations -->
<dependency>
   <groupId>org.eclipse.jetty</groupId>
   <artifactId>jetty-annotations</artifactId>
   <version>9.3.9.M1</version>
</dependency>

[2]并且这种依赖性并未排除在某些奇怪的原因之外。我想jar是指maven依赖。

我的消息来源:

[1] http://grepcode.com/file/repo1.maven.org/maven2/org.eclipse.jetty/jetty-annotations/9.3.2.v20150730/org/eclipse/jetty/annotations/AnnotationConfiguration.java?av=f

[2] http://mvnrepository.com/artifact/org.eclipse.jetty/jetty-annotations/9.3.9.M1

答案 1 :(得分:1)

既然你说你是jetty嵌入式的,那么解决方案很简单。

不要在项目中包含jetty-cdi-*个罐子。 它们不应该用于嵌入式码头。

直接从Jetty Embedded的焊接项目中使用cdi-weld工件。

请务必阅读焊接文档,了解如何设置WebAppClassloader以允许焊接查看服务器组件。 (这称为“在webapp隔离层中打孔”)