【问题标题】:CDI injection is not working in ServletsCDI 注入在 Servlet 中不起作用
【发布时间】:2012-07-29 05:34:10
【问题描述】:

我真的需要你的帮助。我正在研究这个问题数周或数月。对于这篇冗长的帖子,我深表歉意,但我想尽可能准确地解释问题和我的设置。

我的 JAVA EE 6 Web 应用程序主要包含 3 个 Servlet:一个 javax.faces.webapp.FacesServlet、一个扩展 javax.servlet.http.HttpServlet 的 StreamingServlet 和一个 ClientServlet扩展 org.eclipse.jetty.websocket.WebSocketServlet。我想将 CDI 与这些 Servlet 一起使用,但它仅适用于 FacesServlet,更准确地说,适用于 JSF 操作路由到的 Bean。 CDI 注入不适用于其他 2 个 Servlet。

我的项目设置如下:Maven 3.0.4、Jetty 8.1.4 (jetty-maven-plugin)、MyFaces 2.1.6、Weld 1.1.8。

文件 pom.xml 包含 CDI 的依赖项:

...
<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.1.EDR1.2</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>jsr250-api</artifactId>
    <version>1.0</version>
</dependency>
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet</artifactId>
    <version>${weld.version}</version>
    <scope>runtime</scope>
</dependency>
...

文件 src/main/webapp/WEB-INF/beans.xml 只包含一个用于激活 CDI 的空 beans 元素:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

文件 scr/main/webapp/WEB-INF/jetty-env.xml 包含用于通过 JNDI 获取 bean 管理器的 Jetty 特定配置:

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

<Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg>
            <Ref id="webAppCtx" />
        </Arg>
        <Arg>BeanManager</Arg>
        <Arg>
            <New class="javax.naming.Reference">
                <Arg>javax.enterprise.inject.spi.BeanManager</Arg>
                <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>
                <Arg />
            </New>
        </Arg>
    </New>
</Configure>

文件 src/main/webapp/WEB-INF/web.xml 包含 servlet 侦听器和用于引导 CDI 的 BeanManager 参考:

...
<listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>

<resource-env-ref>
    <description>Object factory for the CDI Bean Manager</description>
    <resource-env-ref-name>BeanManager</resource-env-ref-name>
    <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
...

通过这些设置,我在使用 mvn jetty:run 运行应用程序时总是遇到以下错误(第一行是最重要的):

2012-07-31 11:09:33,546 [main] ERROR org.jboss.weld.environment.jetty.JettyPost72Container - Unable to create JettyWeldInjector. CDI injection will not be available in Servlets, Filters or Listeners
java.lang.IllegalArgumentException: Cannot load class for org.jboss.weld.environment.jetty.WeldDecorator
    at org.jboss.weld.environment.servlet.util.Reflections.classForName(Reflections.java:58)
    at org.jboss.weld.environment.jetty.JettyPost72Container.initialize(JettyPost72Container.java:66)
    at org.jboss.weld.environment.servlet.Listener.contextInitialized(Listener.java:162)
    at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:764)
    at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:406)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:756)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:242)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1234)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:699)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:256)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:167)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:90)
    at org.eclipse.jetty.server.Server.doStart(Server.java:262)
    at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:65)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:511)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:364)
    at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:516)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.lang.NoClassDefFoundError: org/eclipse/jetty/servlet/ServletContextHandler$Decorator
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:415)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377)
    at org.jboss.weld.environment.servlet.util.Reflections.classForName(Reflections.java:51)
    ... 44 more
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.servlet.ServletContextHandler$Decorator
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:415)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377)
    ... 56 more

应用程序正在运行,但异常消息指出:CDI 注入在 Servlet 中不可用。

几天前,我发现了文章Starting a CDI webapp from Maven with Weld-Servlet and Jetty Plugin,尤其是允许在servlet 中注入的最后一招部分。作者解释说 Weld 需要装饰一些 Jetty 内部类,以便在 servlet 中使用 @Inject 注解,并且我们必须告诉 Jetty 类加载器在哪里可以找到此类,以便 Weld servlet 对其进行装饰。

我等待这个特殊信息已经等了很久。所以我添加了文件src/main/webapp/WEB-INF/jetty-context.xml

<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

<Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext">
    <Set name="serverClasses">
        <Array type="java.lang.String">
            <Item>org.eclipse.jetty.servlet.ServletContextHandler.Decorator</Item>
        </Array>
    </Set>
</Configure> 

我还更新了 pom.xml 以合并文件 jetty-context.xml(最后一行):

...
<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>${jetty.version}</version>
    <configuration>
        <webApp>
            <contextPath>/${project.build.finalName}</contextPath>
        </webApp>
        <jettyEnvXml>src/main/webapp/WEB-INF/jetty-env.xml</jettyEnvXml>
        <contextXml>src/main/webapp/WEB-INF/jetty-context.xml</contextXml>
        ...

现在上面的错误消失了。在那短暂的一刻我很高兴:)

在 src/main/resources/log4j.properties 我增加了 Weld 的日志级别:

...
log4j.logger.org.jboss.weld=DEBUG, stdout
log4j.additivity.org.jboss.weld=false
...

启动应用程序时,我收到以下焊接日志消息:

...
2012-07-31 12:00:08,968 [main] INFO  org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
2012-07-31 12:00:09,109 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000103 Enabled alternatives for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped, interface javax.enterprise.context.ConversationScoped, interface javax.inject.Singleton]
Registered beans: 0
: [] []
2012-07-31 12:00:09,109 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000104 Enabled decorator types for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped, interface javax.enterprise.context.ConversationScoped, interface javax.inject.Singleton]
Registered beans: 0
: []
2012-07-31 12:00:09,109 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000105 Enabled interceptor types for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped, interface javax.enterprise.context.ConversationScoped, interface javax.inject.Singleton]
Registered beans: 0
: []
2012-07-31 12:00:09,171 [main] INFO  org.jboss.weld.environment.jetty.JettyPost72Container - Jetty7 detected, JSR-299 injection will be available in Listeners, Servlets and Filters.
2012-07-31 12:00:09,265 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Implicit Bean [javax.enterprise.inject.spi.InjectionPoint] with qualifiers [@Default]
2012-07-31 12:00:09,265 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.DependentContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.util.MediaType] with qualifiers [@Any @Default]
2012-07-31 12:00:09,281 [main] WARN  org.jboss.weld.interceptor.util.InterceptionTypeRegistry - Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled
2012-07-31 12:00:09,281 [main] WARN  org.jboss.weld.interceptor.util.InterceptionTypeRegistry - Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.web.LoginBean] with qualifiers [@Any @Default]
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.http.HttpRequestContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.http.HttpSessionContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.web.CustomerBean] with qualifiers [@Any @Default @Named]
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.bound.BoundConversationContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.ApplicationContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.util.LocaleBean] with qualifiers [@Any @Default @Named]
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.bound.BoundRequestContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.SingletonContext
2012-07-31 12:00:09,281 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Implicit Bean [javax.enterprise.inject.Instance] with qualifiers [@Default]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.DataReader] with qualifiers [@Any @Default @Named]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.SessionBean] with qualifiers [@Any @Default @Named]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.ConnectionTable] with qualifiers [@Any @Default @Named]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.http.HttpConversationContext
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.servlet.ClientServlet] with qualifiers [@Any @Default]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.RequestContext
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-javax.enterprise.context.Conversation
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Implicit Bean [javax.enterprise.event.Event] with qualifiers [@Default]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.CustomerListBean] with qualifiers [@Any @Default]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.Customer] with qualifiers [@Any @Default]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.servlet.StreamingServlet] with qualifiers [@Any @Default]
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-Built-in-org.jboss.weld.context.bound.BoundSessionContext
2012-07-31 12:00:09,296 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106 Bean: Managed Bean [class de.telexiom.cardiom.SessionInfo] with qualifiers [@Any @Default]
2012-07-31 12:00:09,312 [main] DEBUG org.jboss.weld.Reflection - WELD-000601 interface javax.inject.Named is missing @Target. Weld will use this annotation, however this may make the application unportable.
2012-07-31 12:00:09,312 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000100 Weld initialized. Validating beans
...

我使用Servlet 3.0 API,StreamingServlet 和ClientServlet 是通过注解配置的。问题是应用程序范围的 bean connectionTabledataReader 没有被注入:

@WebServlet(value = "/stream", initParams = @WebInitParam(name = "maxIdleTime", value = "0"))
public class StreamingServlet extends HttpServlet
{
    @Inject
    private ConnectionTable connectionTable;
    ...

@WebServlet(value = "/push", loadOnStartup = 1, initParams = @WebInitParam(name = "maxIdleTime", value = "0"))
public class ClientServlet extends WebSocketServlet
{
    @Inject
    private ConnectionTable connectionTable;

    @Inject
    private DataReader dataReader;
    ...

调用(未)注入的属性,我总是得到 NullPointerExceptions。通过 web.xml 配置 Servlet 时,问题也仍然存在。我对自己做错了什么没有更多的想法。阅读所有关于 CDI 与 Jetty 和 Maven 结合的文章,我想知道我是否是唯一一个遇到这些注入问题的人。

在我的 JSF bean 类 UserBean.java 中,注入有效,我不必使用 setter 方法来初始化属性 connectionTable 和 dataReader。

在 DataReader 构造函数(以及 ConnectionTable 类)中使用以下输出语句

@ApplicationScoped
public class DataReader implements Serializable
{
    ...
    public DataReader()
    {
        System.out.println("DataReader.DataReader(): " + this);
    }
    ...

我想知道标准输出上显示的 2 个 DataReader 实例:

...
2012-07-31 14:03:04,843 [qtp5435124-17] DEBUG org.jboss.weld.JSF - WELD-000504 Resuming conversation with id null
31.07.2012 14:03:05 org.apache.myfaces.util.ExternalSpecifications isUnifiedELAvailable
INFO: MyFaces Unified EL support enabled
DataReader.DataReader(): DataReader$Proxy$_$$_WeldClientProxy@506e6d
ConnectionTable.ConnectionTable(): ConnectionTable$Proxy$_$$_WeldClientProxy@93b16c

2012-07-31 14:03:19,093 [qtp5435124-16] DEBUG org.jboss.weld.JSF - WELD-000504 Resuming conversation with id null
DataReader.DataReader(): DataReader@1cbd382

前 5 行在基于表单的身份验证后打印,最后 2 行在我的 JSF 操作第一次处理时出现,其中使用了注入的 dataReader 属性。由于 bean 是应用程序范围的,我真的很想知道 2 个构造函数传递。但从应用程序的行为来看,我认为没有任何问题。

我的最后一个假设是 servlet 以某种方式存在于分离的、独立的上下文或容器或类似的东西中。因为在其他 2 个 Servlet 中也无法获取 FacesContext:FacesContext.getCurrentInstance() 给出 null。但我不知道这在某种程度上是否重要。

我希望任何人都可以帮助我找出问题所在。提前谢谢你

塞巴斯蒂安

【问题讨论】:

标签: jakarta-ee servlets jetty cdi jboss-weld


【解决方案1】:

我对这个确切错误消息的 3 天体验,

java.lang.NoClassDefFoundError: javax/enterprise/inject/spi/InjectionTarget

asinstall/glassfish/modules 中的cdi-api.jar 文件被命名为cdi-api-1.2.jar。把名字改成cdi-api.jar,错误就消失了。

规格:

  • Glassfish 4.1(下载为 zip 文件),
  • jdk1.8.0_45,
  • OS X 10.7.5

【讨论】:

    【解决方案2】:

    嗯...你的配置看起来和我的很相似。我不知道的是这个'java-web-api' maven artefact。我在一个新项目中检查了这个,瞧……它有效。然后我又陆续添加了对JSF和WebSocket的支持,还是不行。最后,我弄清楚了错误是什么:我将“jetty-server”人工制品作为依赖项添加到我的 pom.xml 中,但我没有设置范围。所以我使用了错误的服务器库或类似的东西。现在使用“提供”范围时

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>${jetty.version}</version>
        <scope>provided</scope>
    </dependency>
    

    似乎一切正常,依赖注入也在 servlet 中工作。

    关于您的 pom,我还有两个问题:

    1. 你不需要设置 Jetty Maven 插件的 元素吗?

    2. 再次在 Jetty Maven 插件中使用 元素。我使用的是 元素,因为 Eclipse 代码完成知道这一点。这些元素中的一个是否被弃用而取而代之?

    【讨论】:

      【解决方案3】:

      对于任何试图应用@Roosevelt Lai 建议的人,我将 jetty-web.xml 中调用的方法的名称更改为 &lt;Call name="addServerClass"&gt;&lt;Arg&gt;-org.eclipse.jetty.servlet.&lt;/Arg&gt;&lt;/Call&gt;,因为我遇到了 NoSuchMethod 异常。

      docs here中所示

      码头(8.1.14.v20131031)

      【讨论】:

        【解决方案4】:

        错误很明显:

        java.lang.NoClassDefFoundError: org/eclipse/jetty/servlet/ServletContextHandler$Decorator
        

        Weld 找不到上述 Jetty 服务器类。找不到这个类的原因是Jetty的类加载机制。 Jetty 的 WebAppClassloader 有一个默认的服务器类列表,它不会加载:参见http://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading

        Server Classes
        -org.eclipse.jetty.continuation.             don't hide continuation classes
        -org.eclipse.jetty.jndi.                     don't hide naming classes
        -org.eclipse.jetty.plus.jaas.                don't hide jaas classes
        -org.eclipse.jetty.websocket.                don't hide websocket extension
        -org.eclipse.jetty.servlet.DefaultServlet    don't hide default servlet
        org.eclipse.jetty.                           hide all other jetty classes
        

        要让 Jetty 加载这个类,你需要添加“-org.eclipse.jetty.servlet”。到 jetty-web.xml 中的服务器类列表。

         <Configure class="org.eclipse.jetty.webapp.WebAppContext">
           <Call name="prependServerClass"><Arg>-org.eclipse.jetty.servlet.</Arg></Call>
         </Configure>
        

        如果您使用的是嵌入式码头,请调用以下方法:

         context.prependServerClass("-org.eclipse.jetty.servlet.");
        

        【讨论】:

          猜你喜欢
          • 2014-08-30
          • 2018-10-26
          • 2012-04-30
          • 1970-01-01
          • 2014-02-17
          • 1970-01-01
          • 2017-09-24
          • 2018-08-06
          • 2020-03-04
          相关资源
          最近更新 更多