Использование CDI/Deltaspike с причалом

Для модуля dropwizard я пытаюсь использовать deltaspike и cdi с автономным сервером jetty.

Изменить (из комментария): «Мой вопрос (забудьте слово dropwizard): как мне использовать deltaspike/weld/jetty вместе, почему пример кода в документации deltaspike не работает?»

Согласно документации, это нужно просто сделать, добавив ServletListener, но все Я получаю NPE, так как «Bar» не вводится.

Вот пример кода, который я использую.

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());
    }
}

person Jan Galinski    schedule 11.01.2015    source источник
comment
Похоже, ваша проблема больше связана с dropwizard/jetty. Есть ли что-нибудь, что могло бы обеспечить поддержку инъекций через dropwizard для сервлетов причала? Dropwizard использует guice, а не CDI.   -  person John Ament    schedule 11.01.2015
comment
Вы правы, я хочу использовать CDI с dropwizard. Guice не вариант, так как я хочу запустить существующее приложение на основе CDI как микросервис и не могу переписать его для guice. Тем не менее, в приведенном выше примере не используется dropwizard, я использую только зависимости, указанные в документации deltaspike для использования с причалом... и терплю неудачу.   -  person Jan Galinski    schedule 12.01.2015
comment
Однако DropWizard специально предназначен для Guice, вы не можете просто поменять местами другой контейнер IoC и ожидать, что он будет работать. Может быть, вы хотите взглянуть на Hammock — github.com/johnament/hammock   -  person John Ament    schedule 12.01.2015
comment
Сам Dropwizard не использует guice, вообще не использует DI (кроме майки hk2). Существует несколько неофициальных расширений guice, которые позволяют использовать DI с guice, вот и все. То же самое с весной. Мой вопрос (забудьте слово dropwizard): как мне использовать deltaspike/weld/jetty вместе, почему пример кода в документации deltaspiek не работает?   -  person Jan Galinski    schedule 12.01.2015
comment
Столкнулся с той же проблемой. ServletContextHandler зависит от Jetty и вызывает addServlet(BarServlet.class, /*); заставляет ServletContextHandler использовать ServletHolder, который использует метод getInstance() класса java.lang.Class, который, конечно, полностью не поддерживает CDI. Пользовательская реализация ServletHolder может служить обходным путем, но я ожидаю, что DeltaSpike будет поддерживать что-то подобное из коробки.   -  person Kamaruni    schedule 30.01.2015
comment
Спасибо за отзыв, уже начал думать, что пытаюсь что-то очень глупое... тем временем пользуюсь spring-boot. Я все еще заинтересован в решении dw/deltaspike, но это не давало мне работать над реальной проблемой.   -  person Jan Galinski    schedule 30.01.2015
comment
Основываясь на вашем коде здесь, Bar не является допустимым bean-компонентом для инъекции. CDI не сканирует внутренние классы.   -  person John Ament    schedule 02.02.2015
comment
@JanGalinski Вы заставили Delta Spike работать с Dropwizard?   -  person Hervian    schedule 21.06.2017
comment
Нет, я недавно перешел на весеннюю загрузку.   -  person Jan Galinski    schedule 21.06.2017


Ответы (1)


В настоящее время я работаю с:

  • JBoss Weld 3.0.1 Финал
  • Apache DeltaSpike 1.8.0
  • Причал 9.4.7.v20170914

Эти версии были выбраны для определенной цели; Weld 3 — это реализация CDI 2.0. DeltaSpike 1.8.0 — это расширение CDI 2. И версия Jetty также важна, так как эта версия (и выше) имеет часть интеграции CDI.

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

Как вы видите во второй зависимости: cdi-servlet гарантирует, что jetty запустит сервлет интеграции cdi. Тогда ваш основной класс может быть просто:

  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();
person Ivo Limmen    schedule 03.01.2018