1

For a dropwizard module I am trying to use deltaspike and cdi with a jetty standalone server.

Edit (from comment): "My question (forget the word dropwizard): How do I use deltaspike/weld/jetty together, why does the sample code in the deltaspike documentation not work?"

According to the documentation, it should be simply done by adding a ServletListener, but all I get is a NPE, since "Bar" doesn't get injected.

Here is the sample code I use.

import org.apache.deltaspike.cdise.api.CdiContainer;
import org.apache.deltaspike.cdise.api.CdiContainerLoader;
import org.apache.deltaspike.cdise.servlet.CdiServletRequestListener;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.slf4j.bridge.SLF4JBridgeHandler;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class BarServlet extends HttpServlet {

    static {
        SLF4JBridgeHandler.removeHandlersForRootLogger();
        SLF4JBridgeHandler.install();
    }

    public static void main(String... args) throws Exception {
        CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
        cdiContainer.boot();
        cdiContainer.getContextControl().startContexts();

        Server server = new Server(1234);
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        context.addEventListener(new CdiServletRequestListener());
        context.addServlet(BarServlet.class, "/*");

        server.start();
    }

    public static class Bar {
        public String hello() {
            return "bar";
        }
    }

    @Inject
    private Bar bar;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().print(bar.hello());
    }
}
Jan Galinski
  • 11,768
  • 8
  • 54
  • 77
  • It seems like your issue is more dropwizard/jetty related. Is there anything would provide injection support via dropwizard for jetty servlets? Dropwizard leverages guice, not CDI. – John Ament Jan 11 '15 at 19:16
  • You are right, I want to use CDI with dropwizard. Guice is not an option since I want to run an existing CDI-based application as microservice and cannot rewrite it for guice. Still, the example above does not use dropwizard, I use only the dependencies stated in the deltaspike documentation for use with jetty ... and fail. – Jan Galinski Jan 11 '15 at 21:09
  • DropWizard is specifically for Guice though, you can't just swap in a different IoC container and expect it to work. Maybe you want to look at Hammock - https://github.com/johnament/hammock – John Ament Jan 11 '15 at 21:39
  • Dropwizard itself doesn't use guice, it doesn't use DI at all (except for jerseys hk2). There exist several unofficial guice extensions that allow DI with guice, that's all. Same with spring. My question (forget the word dropwizard): How do I use deltaspike/weld/jetty together, why does the sample code in the deltaspiek documentation not work? – Jan Galinski Jan 11 '15 at 21:51
  • Am facing the same problem. ServletContextHandler is Jetty specific, calling addServlet(BarServlet.class, "/*"); causes ServletContextHandler to use ServletHolder, which uses the getInstance() method of java.lang.Class, which is, of course, completely CDI-unaware. A custom implementation of ServletHolder could serve as workaround, but I'd expect DeltaSpike to support something like this out of the box. – Kamaruni Jan 29 '15 at 21:56
  • Thanks for the feedback, I was beginning to think that I was trying something very stupid ... meanwhile I use spring-boot. I am still interested in a dw/deltaspike solution, but it kept me from working on the real problem. – Jan Galinski Jan 30 '15 at 12:23
  • Based on your code here, `Bar` is not a valid bean for injection. CDI does not scan for inner classes. – John Ament Feb 02 '15 at 11:55
  • @JanGalinski Did you get Delta Spike to work with Dropwizard? – Hervian Jun 21 '17 at 09:14
  • No, I switched to spring-boot a while ago. – Jan Galinski Jun 21 '17 at 09:25

1 Answers1

0

I am currently working with:

  • JBoss Weld 3.0.1Final
  • Apache DeltaSpike 1.8.0
  • Jetty 9.4.7.v20170914

These versions where selected for a purpose; Weld 3 is a CDI 2.0 implementation. DeltaSpike 1.8.0 is a CDI 2 extension. And the version of Jetty is also important as that version (and higher) has a CDI integration part.

     <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-bom</artifactId>
        <version>9.4.7.v20170914</version>              
        <scope>import</scope>
        <type>pom</type>
     </dependency>          
     <dependency>
        <groupId>org.eclipse.jetty.cdi</groupId>
        <artifactId>cdi-servlet</artifactId>
        <version>9.4.7.v20170914</version>              
     </dependency>

As you see in the second dependency: the cdi-servlet will make sure jetty will start the cdi integration servlet. You main class can then simply be:

  Server server = new Server(8080);

  WebAppContext context = new WebAppContext();
  context.setConfigurations(new Configuration[]{
     new AnnotationConfiguration(),
     new WebInfConfiguration(),
     new WebXmlConfiguration(),
     new MetaInfConfiguration(),
     new FragmentConfiguration(),
     new EnvConfiguration(),
     new PlusConfiguration(),
     new JettyWebXmlConfiguration()}
  );
  context.setContextPath("/");
  context.setResourceBase("src/main/webapp");
  context.setParentLoaderPriority(true);
  server.setHandler(context);

  server.start();

  // example...
  CDI.current().select(Servlet.class).forEach(s ->
     context.addServlet(s.getClass(), s.getClass().getSimpleName());
  });

  server.join();
Ivo Limmen
  • 3,095
  • 1
  • 26
  • 23