WELD-001408: Unsatisfied dependencies for type Logger with qualifiers @Default at injection point [BackedAnnotatedField] @Inject

huangapple go评论112阅读模式
英文:

WELD-001408: Unsatisfied dependencies for type Logger with qualifiers @Default at injection point [BackedAnnotatedField] @Inject

问题

我在测试一个使用 Arquillian 的 JavaEE8 应用程序时遇到了问题:WELD-001408:对于带有 @Default 限定符的 Logger 类型的不满足的依赖关系
在注入点 [BackedAnnotatedField] @Inject private academy.learnprogramming.services.TodoService.LOG 处

我对注入的 EntityManager 也有相同的错误

以下是我的类:

TodoService.class(我需要测试的类)

  1. package academy.learnprogramming.services;
  2. import academy.learnprogramming.entities.Todo;
  3. import org.apache.log4j.Logger;
  4. import javax.annotation.PostConstruct;
  5. import javax.inject.Inject;
  6. import javax.persistence.EntityManager;
  7. import javax.transaction.Transactional;
  8. import java.util.List;
  9. @Transactional
  10. public class TodoService {
  11. @Inject
  12. private Logger LOG = Logger.getLogger(TodoService.class);
  13. @Inject
  14. EntityManager entityManager;
  15. public Todo createTodo(Todo todo) {
  16. //将数据持久化到数据库
  17. entityManager.persist(todo);
  18. return todo;
  19. }
  20. public Todo updateTodo(Todo todo) {
  21. entityManager.merge(todo);
  22. return todo;
  23. }
  24. @PostConstruct
  25. private void init() {
  26. LOG.info("Bean TodoService created");
  27. }
  28. public Todo findTodoById(Long id) {
  29. return entityManager.find(Todo.class, id);
  30. }
  31. public List<Todo> getTodos(){
  32. return entityManager.createQuery("SELECT t from Todo t", Todo.class).getResultList();
  33. }
  34. }

TodoServiceTest.class(用于测试的类)

  1. package academy.learnprogramming.services;
  2. import academy.learnprogramming.config.Producers;
  3. import academy.learnprogramming.entities.Todo;
  4. import org.jboss.arquillian.container.test.api.Deployment;
  5. import org.jboss.arquillian.junit.Arquillian;
  6. import org.jboss.shrinkwrap.api.ShrinkWrap;
  7. import org.jboss.shrinkwrap.api.asset.EmptyAsset;
  8. import org.jboss.shrinkwrap.api.spec.JavaArchive;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12. import org.junit.runner.RunWith;
  13. import static org.junit.Assert.*;
  14. @RunWith(Arquillian.class)
  15. public class TodoServiceTest {
  16. @Deployment
  17. public static JavaArchive createDeployment() {
  18. return ShrinkWrap.create(JavaArchive.class)
  19. .addClasses(TodoService.class, Todo.class, Producers.class)
  20. .addAsResource("persistence.xml", "META-INF/persistence.xml")
  21. .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
  22. }
  23. @Before
  24. public void setUp() throws Exception {
  25. }
  26. @After
  27. public void tearDown() throws Exception {
  28. }
  29. @Test
  30. public void createTodo() {
  31. }
  32. @Test
  33. public void updateTodo() {
  34. }
  35. @Test
  36. public void findTodoById() {
  37. }
  38. @Test
  39. public void getTodos() {
  40. }
  41. }

Producers.class(用于将第三方库添加到 CDI 的类)

  1. package academy.learnprogramming.config;
  2. import org.apache.log4j.Logger;
  3. import org.dozer.DozerBeanMapper;
  4. import javax.enterprise.context.RequestScoped;
  5. import javax.enterprise.inject.Produces;
  6. import javax.enterprise.inject.spi.InjectionPoint;
  7. import javax.persistence.EntityManager;
  8. import javax.persistence.PersistenceContext;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. public class Producers {
  12. @Produces
  13. @PersistenceContext
  14. EntityManager entityManager;
  15. @Produces
  16. public Logger produceLogger(InjectionPoint injectionPoint) {
  17. return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
  18. }
  19. @Produces
  20. public DozerBeanMapper produceDozerBeanMapper() {
  21. DozerBeanMapper mapper = new DozerBeanMapper();
  22. List<String> mappingFiles = new ArrayList<>();
  23. mappingFiles.add("dozerJdk8Converters.xml");
  24. mapper.setMappingFiles(mappingFiles);
  25. return mapper;
  26. }
  27. }

在我搜索了一些信息后,我了解到可能的问题可能是:

  1. 如果你没有将 bean-discovery-mode 设置为 "all"beans.xml 可能会导致问题,因为它不会扫描未注释的 bean,但是我的 beans.xml 文件已经设置了 bean-discovery-mode="all"
  2. 注入到 TodoService 类中的 Logger 和 EntityManager 可能没有 Producer,但我已经有了 Producers
  3. 人们在为 TodoServiceTodoServiceTestProducers 类导入 Logger 类时可能会犯错,例如在一个类中导入 org.apache.log4j.Logger,在另一个类中导入 java.util.logging.Logger,但我所有的类都使用了 import org.apache.log4j.Logger

如果我移除 @Inject 注解并且直接从类中使用 logger,那么它可以正常工作。

还有什么其他尝试的方法吗?非常感谢您的时间。

英文:

I'm having this problem while testing a JavaEE8 application with Arquillian: WELD-001408: Unsatisfied dependencies for type Logger with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private academy.learnprogramming.services.TodoService.LOG

I have the same error for the injected EntityManager

These are my classes:

TodoService.class (the class that I have to test)

  1. package academy.learnprogramming.services;
  2. import academy.learnprogramming.entities.Todo;
  3. import org.apache.log4j.Logger;
  4. import javax.annotation.PostConstruct;
  5. import javax.inject.Inject;
  6. import javax.persistence.EntityManager;
  7. import javax.transaction.Transactional;
  8. import java.util.List;
  9. @Transactional
  10. public class TodoService {
  11. @Inject
  12. private Logger LOG = Logger.getLogger(TodoService.class);
  13. @Inject
  14. EntityManager entityManager;
  15. public Todo createTodo(Todo todo) {
  16. //Persist into db
  17. entityManager.persist(todo);
  18. return todo;
  19. }
  20. public Todo updateTodo(Todo todo) {
  21. entityManager.merge(todo);
  22. return todo;
  23. }
  24. @PostConstruct
  25. private void init() {
  26. LOG.info(&quot;Bean TodoService created&quot;);
  27. }
  28. public Todo findTodoById(Long id) {
  29. return entityManager.find(Todo.class, id);
  30. }
  31. public List&lt;Todo&gt; getTodos(){
  32. return entityManager.createQuery(&quot;SELECT t from Todo t&quot;, Todo.class).getResultList();
  33. }
  34. }

TodoServiceTest.class (The class used for testing)

  1. package academy.learnprogramming.services;
  2. import academy.learnprogramming.config.Producers;
  3. import academy.learnprogramming.entities.Todo;
  4. import org.jboss.arquillian.container.test.api.Deployment;
  5. import org.jboss.arquillian.junit.Arquillian;
  6. import org.jboss.shrinkwrap.api.ShrinkWrap;
  7. import org.jboss.shrinkwrap.api.asset.EmptyAsset;
  8. import org.jboss.shrinkwrap.api.spec.JavaArchive;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12. import org.junit.runner.RunWith;
  13. import static org.junit.Assert.*;
  14. @RunWith(Arquillian.class)
  15. public class TodoServiceTest {
  16. @Deployment
  17. public static JavaArchive createDeployment() {
  18. return ShrinkWrap.create(JavaArchive.class)
  19. .addClasses(TodoService.class, Todo.class, Producers.class)
  20. .addAsResource(&quot;persistence.xml&quot;, &quot;META-INF/persistence.xml&quot;)
  21. .addAsManifestResource(EmptyAsset.INSTANCE, &quot;beans.xml&quot;);
  22. }
  23. @Before
  24. public void setUp() throws Exception {
  25. }
  26. @After
  27. public void tearDown() throws Exception {
  28. }
  29. @Test
  30. public void createTodo() {
  31. }
  32. @Test
  33. public void updateTodo() {
  34. }
  35. @Test
  36. public void findTodoById() {
  37. }
  38. @Test
  39. public void getTodos() {
  40. }
  41. }

Producers.class (Class used to add 3rd party libraries to CDI)

  1. package academy.learnprogramming.config;
  2. import org.apache.log4j.Logger;
  3. import org.dozer.DozerBeanMapper;
  4. import javax.enterprise.context.RequestScoped;
  5. import javax.enterprise.inject.Produces;
  6. import javax.enterprise.inject.spi.InjectionPoint;
  7. import javax.persistence.EntityManager;
  8. import javax.persistence.PersistenceContext;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. //If producers becomes complitated, split it in many classes, each for a single producer
  12. public class Producers {
  13. @Produces
  14. @PersistenceContext
  15. EntityManager entityManager;
  16. @Produces
  17. public Logger produceLogger(InjectionPoint injectionPoint) {
  18. return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
  19. }
  20. //Auto mapper
  21. @Produces
  22. public DozerBeanMapper produceDozenBeanMapper() {
  23. DozerBeanMapper mapper = new DozerBeanMapper();
  24. List&lt;String&gt; mappingFiles = new ArrayList();
  25. mappingFiles.add(&quot;dozerJdk8Converters.xml&quot;);
  26. mapper.setMappingFiles(mappingFiles);
  27. return mapper;
  28. }
  29. }

Searching around, I understood that possible problems could be:

  1. beans.xml could give problems if you don't put bean-discovery-mode="all", because it won't scan for not annotated beans, but my beans.xml file has bean-discovery-mode="all"
  2. The Logger and the EntityManager injected into the TodoService class could not have a Producer, but I have the Producers class
  3. People can make mistakes during the import of Logger class for TodoService, TodoServiceTest and Producers classes, having for example import org.apache.log4j.Logger in one class, and java util.logging.Logger for another, but I have all classes with import org.apache.log4j.Logger

If I remove the @Inject annotation and I use the logger from the classes, It works.

What else can I try?
Thank you a lot for your time.

答案1

得分: 0

尝试在使用WAR文件时使用WebArchive

  1. @Deployment
  2. public static WebArchive createDeployment() {
  3. return ShrinkWrap.create(WebArchive.class)
  4. .addClasses(TodoService.class, Todo.class, Producers.class)
  5. .addAsResource("persistence.xml", "META-INF/persistence.xml")
  6. .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
  7. }

移除Logger.getLogger(TodoService.class);,生产者将会实例化日志记录器。

  1. @RequestScoped
  2. @Transactional
  3. public class TodoService {
  4. @Inject
  5. private Logger log;
  6. @Inject
  7. EntityManager entityManager;
  8. public Todo createTodo(Todo todo) {
  9. //向数据库持久化
  10. entityManager.persist(todo);
  11. return todo;
  12. }
  13. public Todo updateTodo(Todo todo) {
  14. entityManager.merge(todo);
  15. return todo;
  16. }
  17. @PostConstruct
  18. private void init() {
  19. log.info("Bean TodoService已创建");
  20. }
  21. public Todo findTodoById(Long id) {
  22. return entityManager.find(Todo.class, id);
  23. }
  24. public List<Todo> getTodos(){
  25. return entityManager.createQuery("SELECT t from Todo t", Todo.class).getResultList();
  26. }
  27. }
英文:

Try to use the WebArchive if you use a WAR file

  1. @Deployment
  2. public static WebArchive createDeployment() {
  3. return ShrinkWrap.create(WebArchive.class)
  4. .addClasses(TodoService.class, Todo.class, Producers.class)
  5. .addAsResource(&quot;persistence.xml&quot;, &quot;META-INF/persistence.xml&quot;)
  6. .addAsManifestResource(EmptyAsset.INSTANCE, &quot;beans.xml&quot;);
  7. }

remove the Logger.getLogger(TodoService.class); the producer it's going to instantiate the logger.

  1. @RequestScoped
  2. @Transactional
  3. public class TodoService {
  4. @Inject
  5. private Logger log;
  6. @Inject
  7. EntityManager entityManager;
  8. public Todo createTodo(Todo todo) {
  9. //Persist into db
  10. entityManager.persist(todo);
  11. return todo;
  12. }
  13. public Todo updateTodo(Todo todo) {
  14. entityManager.merge(todo);
  15. return todo;
  16. }
  17. @PostConstruct
  18. private void init() {
  19. log.info(&quot;Bean TodoService created&quot;);
  20. }
  21. public Todo findTodoById(Long id) {
  22. return entityManager.find(Todo.class, id);
  23. }
  24. public List&lt;Todo&gt; getTodos(){
  25. return entityManager.createQuery(&quot;SELECT t from Todo t&quot;, Todo.class).getResultList();
  26. }

huangapple
  • 本文由 发表于 2020年8月20日 01:14:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63491903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定