Skip to content

Latest commit

 

History

History
200 lines (166 loc) · 8.12 KB

File metadata and controls

200 lines (166 loc) · 8.12 KB

Weld

Weld can be used to add support for CDI (Contexts and Dependency Injection) to Servlets, Listeners and Filters. It is easily configured with Jetty 9.

Weld Setup

The easiest way to configure weld is within the Jetty distribution itself. This can be accomplished either by enabling one of the startup modules described in CDI Framework:

  • the cdi-decorate module is the preferred Weld integration. The activation of this module by Weld can be confirmed by the following Weld log:

INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters.
  • the cdi-spi module works with Weld, but may restrict some non standard features. The activation of this module by Weld can be confirmed by the following Weld log:

INFO: WELD-ENV-001213: Jetty CDI SPI support detected, CDI injection will be available in Listeners, Servlets and Filters.
  • the deprecated cdi2 module works with Weld prior to 3.1.2.Final. The activation of this module by Weld can be confirmed by the following Weld log:

INFO: WELD-ENV-001201: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported.

To activate the preferred cdi-decorate module use:

cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-decorate
Tip
For use with the jetty-maven-plugin, the best idea is to make the org.jboss.weld.servlet:weld-servlet and jetty-cdi artifacts plugin dependencies (not a webapp dependency).

Embedded Jetty

When starting embedded Jetty programmatically from the main method it is necessary to:

  • enable a jetty CDI integration mode by registering a Listener or ServletContainerInitializer

  • enable Weld by registering either its Listener or ServletContainerInitializer

Using a ServletContextHandler

Embedded usage often uses a ServletContextHandler which is the base class of WebappContext and lacks the features of "web.xml" configuration and must be configured directly. The examples in this section based on a server and context set up as follows:

public class Main {
    public static void main(String[] args) throws Exception {
        Server jetty = new Server(8080);
        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        server.setHandler(context);

        context.addServlet(HelloWorldServlet.class, "/*");

        /* CDI enabling goes here. See options below */

        jetty.start();
        jetty.join();
    }

    public static class HelloWorldServlet extends HttpServlet {

        @Inject BeanManager manager;

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/plain");
            resp.getWriter().append("Hello from " + manager);
        }
    }
}
Initialize Weld with ServletContainerInitializers

The best way to initialize both Jetty Weld integration is to use their respective ServletContainerInitializers:

    import org.eclipse.jetty.cdi.CdiServletContainerInitializer;
    import org.eclipse.jetty.cdi.CdiDecoratingListener;
    import org.jboss.weld.environment.servlet.EnhancedListener;
    // ...
        context.setInitParameter(
            CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
            CdiDecoratingListener.MODE);
        context.addBean(new ServletContextHandler.Initializer(context,
            new EnhancedListener()));
        context.addBean(new ServletContextHandler.Initializer(context,
            new CdiServletContainerInitializer()));

This code uses the ServletContextHandler.Initializer utility class added in Jetty-9.4.30. Prior to that the same effect can be achieved with a custom implementation of ServletContextHandler.ServletContainerInitializerCaller.

Initialize Weld with Listeners

Jetty Weld integration can also be initialized by directly adding the listeners required:

    import org.eclipse.jetty.cdi.CdiDecoratingListener;
    import org.jboss.weld.environment.servlet.Listener;
    // ...
        context.addEventListener(new CdiDecoratingListener(context));
        context.addEventListener(new Listener());
Other Weld initializations

When running embedded without a context classloader, it is not actually required to initialize Jetty at all. If just Weld is initialized then it will disover the Jetty APIs and use the deprecated integration:

    import org.jboss.weld.environment.servlet.Listener;
    // ...
        context.addEventListener(new Listener());

However, this results in only a partially functional integration and the following warning:

INFO: WELD-ENV-001201: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported.

Jetty can also be initialized by adding the org.eclipse.jetty.webapp.DecoratingListener listener instead of the org.eclipse.jetty.cdi.CdiDecoratingListener. However, this introduces a needless dependency on jetty-webapp and is not the preferred method.

Initialize Weld with WebappContext

Some embedded usage still makes use of the WebappContext class for the convention-over-configuration benefits. The methods described for ServletContextHandler will work for WebappContext:

    import org.eclipse.jetty.cdi.CdiServletContainerInitializer;
    import org.eclipse.jetty.cdi.CdiDecoratingListener;
    import org.jboss.weld.environment.servlet.EnhancedListener;
    // ...
        Server server = new Server(8080);
        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/");
        server.setHandler(webapp);

        webapp.setInitParameter(
            CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
            CdiDecoratingListener.MODE);
        webapp.addBean(new ServletContextHandler.Initializer(webapp,
            new CdiServletContainerInitializer()));
        webapp.addBean(new ServletContextHandler.Initializer(webapp,
            new EnhancedListener()));

        // ...

Alternately the webapp can be configured to discover the SCIs:

        Server server = new Server(8080);
        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/");
        server.setHandler(webapp);

        webapp.setInitParameter(
            CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
            CdiDecoratingListener.MODE);

        // Need the AnnotationConfiguration to detect SCIs
        Configuration.ClassList.setServerDefault(server).addBefore(
            JettyWebXmlConfiguration.class.getName(),
            AnnotationConfiguration.class.getName());

        // Need to expose our SCI class.
        webapp.getServerClasspathPattern().add("-" + CdiServletContainerInitializer.class.getName());
        webapp.getSystemClasspathPattern().add(CdiServletContainerInitializer.class.getName());

        // ...