Deploying a war to Jetty with CDI

不问归期 提交于 2019-11-28 13:06:52
Antoine Sabot-Durand

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.

Jetty 9.1.0+ requires Weld 2.2.0+

See: https://issues.jboss.org/browse/WELD-1561

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!