Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
642 views
in Technique[技术] by (71.8m points)

maven - Deploying a war to Jetty with CDI

I have a maven project in IntelliJ where I am trying to deploy a war file to a jetty container. The purpose of this is for a quick integration test of some of the functionality in said war file.

Since out of the box Jetty does not come with CDI or JNDI, I am trying to add support for these but running into some issues. For example, I get the following error on startup:

15:30:50 [34mINFO [0;39m o.a.s.c.CdiObjectFactory - [lookup]: Checking for BeanManager under JNDI key java:comp/BeanManager 
15:30:50 [39mDEBUG[0;39m o.a.s.c.CdiObjectFactory - [lookup]: BeanManager lookup failed for JNDI key java:comp/BeanManager 

I have included the weld-servlet jar in my pom and also added the weld listener to the web.xml, however it still does not work. I am using Jetty 9. Any ideas?

pom.xml

    <dependency>
        <groupId>org.jboss.weld.servlet</groupId>
        <artifactId>weld-servlet-core</artifactId>
        <version>2.0.4.Final</version>
    </dependency>

web.xml

<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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The following config works for me on Jetty 8.x and 9.0.x (not 9.1+ for the moment)

Here are the config needed :

Add the dependency in Pom.xml

....
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet</artifactId>
    <version>2.1.0.Final</version>
</dependency>
....

note the fact that i'm using weld-servletdependency which contains all needed Weld and CDI classes.

In jetty-env.xml you declare the JNDI ressources

<!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>

in web.xml you add the listener and expose the JNDI resource :

...
<listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
...
<resource-env-ref>
    <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>
...

And eventually if you want to be able to inject bean in servlet you need to ask Jetty to expose some of its inner class by creating the following jetty-web.xml file in your WEB-INF directory

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

Dont miss the - in <Item/>, it's the way to tell Jetty that a class is no more an inner class and can be seen by the webapp. With that Weld will be able to decorate Jetty inner servlet class to add CDI Injection support in it.

Bonus : using the jetty plugin for Maven

It's quite easy, you'll only have to add a runprofile to your pom.xmllike this

<profile>
    <id>run</id>
    <build>
        <defaultGoal>clean jetty:run-forked</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.0.7.v20131107</version>
                <configuration>
                    <stopPort>1353</stopPort>
                    <stopKey>quit</stopKey>
                    <contextXml>src/main/webapp/WEB-INF/jetty-web.xml</contextXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
</profile>

After that you'll only have to type mvn -Prun to build your app, launch Jetty and deploy the app in it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...