Я пытаюсь использовать CDI в своем очень простом веб-приложении, которое работает в профиле Websphere Liberty, установленном через Docker.Инъекция зависимостей Java EE в профиле Websphere Liberty
Однако впрыска завершается с ошибкой, если я не укажу аннотацию области (например, @ApplicationScoped
) на инжектируемый компонент, хотя, согласно множеству онлайн-руководств (например, this), спецификации Java EE не требуют этого.
Ниже приведен код, который не удается:
HelloWorldServlet.java
package my.simple.app;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
static String PAGE_HEADER = "<html><head /><body>";
static String PAGE_FOOTER = "</body></html>";
@Inject
HelloService helloService;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println(PAGE_HEADER);
writer.println("<h1>" + helloService.createHelloMessage("World") + "</h1>");
writer.println(PAGE_FOOTER);
writer.close();
}
}
HelloService.java
package my.simple.app;
public class HelloService {
String createHelloMessage(String name) {
return "Hello " + name + "!";
}
}
server.xml (Docker изображение-свобода WebSphere: javaee7)
<server description="default servlet engine">
<httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" httpsPort="9443" />
<!-- Enable features -->
<featureManager>
<feature>servlet-3.1</feature>
<feature>cdi-1.2</feature>
</featureManager>
</server>
Однако я получаю эту ошибку
Error 404: javax.servlet.UnavailableException: SRVE0319E: For the [my.simple.app.HelloWorldServlet] servlet, my.simple.app.HelloWorldServlet servlet class was found, but a resource injection failure has occurred. The @Inject java.lang.reflect.Field.helloService reference of type my.simple.app.HelloService for the null component in the app.war module of the app application cannot be resolved.
Однако, как только я добавить @ApplicationScoped
в HelloService все начинает работать.
Что я делаю неправильно?
Решение:
В CDI1.2 (который я использую) по умолчанию только аннотированные бобы обнаружены. Для того, чтобы все бобы быть обнаружены, и режим явного открытия должен быть включен в beans.xml
Ссылки:
- Packaging considerations
- Enabling the CDI feature in Websphere Liberty
- About implicit and explicit beans discovery
Спасибо, это было! Обновил мой собственный комментарий для решения. –