WELD-001408:在注入点 [BackedAnnotatedField] @Inject 具有限定符 @Default 的类型 Logger 的不满足依赖关系
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 有同样的错误
这些是我的 classes:
TodoService.class(我要测试的class)
package academy.learnprogramming.services;
import academy.learnprogramming.entities.Todo;
import org.apache.log4j.Logger;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.util.List;
@Transactional
public class TodoService {
@Inject
private Logger LOG = Logger.getLogger(TodoService.class);
@Inject
EntityManager entityManager;
public Todo createTodo(Todo todo) {
//Persist into db
entityManager.persist(todo);
return todo;
}
public Todo updateTodo(Todo todo) {
entityManager.merge(todo);
return todo;
}
@PostConstruct
private void init() {
LOG.info("Bean TodoService created");
}
public Todo findTodoById(Long id) {
return entityManager.find(Todo.class, id);
}
public List<Todo> getTodos(){
return entityManager.createQuery("SELECT t from Todo t", Todo.class).getResultList();
}
}
TodoServiceTest.class(用于测试的class)
package academy.learnprogramming.services;
import academy.learnprogramming.config.Producers;
import academy.learnprogramming.entities.Todo;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(Arquillian.class)
public class TodoServiceTest {
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(TodoService.class, Todo.class, Producers.class)
.addAsResource("persistence.xml", "META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void createTodo() {
}
@Test
public void updateTodo() {
}
@Test
public void findTodoById() {
}
@Test
public void getTodos() {
}
}
Producers.class(Class 用于将第 3 方库添加到 CDI)
package academy.learnprogramming.config;
import org.apache.log4j.Logger;
import org.dozer.DozerBeanMapper;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;
//If producers becomes complitated, split it in many classes, each for a single producer
public class Producers {
@Produces
@PersistenceContext
EntityManager entityManager;
@Produces
public Logger produceLogger(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
//Auto mapper
@Produces
public DozerBeanMapper produceDozenBeanMapper() {
DozerBeanMapper mapper = new DozerBeanMapper();
List<String> mappingFiles = new ArrayList();
mappingFiles.add("dozerJdk8Converters.xml");
mapper.setMappingFiles(mappingFiles);
return mapper;
}
}
四处寻找,我了解到可能的问题可能是:
- beans.xml 如果您不放置 bean-discovery-mode="all" 可能会出现问题,因为它不会扫描未注释的 bean,但我的 beans.xml 文件有 bean -发现模式=“全部”
- 注入到 TodoService 中的 Logger 和 EntityManager class 不能有生产者,但我有生产者 class
- 人们在为 TodoService、TodoServiceTest 和 Producers classes 导入 Logger class 的过程中可能会出错,例如在一个 org.apache.log4j.Logger 中导入=51=] 和 java util.logging.Logger 另一个,但我有所有 classes 导入 org.apache.log4j.Logger
如果我删除 @Inject 注释并使用 classes 中的记录器,它会起作用。
我还能尝试什么?
非常感谢您的宝贵时间。
如果您使用 WAR 文件,请尝试使用 WebArchive
@Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class)
.addClasses(TodoService.class, Todo.class, Producers.class)
.addAsResource("persistence.xml", "META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
删除 Logger.getLogger(TodoService.class);
将要实例化记录器的生产者。
@RequestScoped
@Transactional
public class TodoService {
@Inject
private Logger log;
@Inject
EntityManager entityManager;
public Todo createTodo(Todo todo) {
//Persist into db
entityManager.persist(todo);
return todo;
}
public Todo updateTodo(Todo todo) {
entityManager.merge(todo);
return todo;
}
@PostConstruct
private void init() {
log.info("Bean TodoService created");
}
public Todo findTodoById(Long id) {
return entityManager.find(Todo.class, id);
}
public List<Todo> getTodos(){
return entityManager.createQuery("SELECT t from Todo t", Todo.class).getResultList();
}
我在使用 Arquillian 测试 JavaEE8 应用程序时遇到了这个问题:WELD-001408:带有限定符 @Default 的类型 Logger 的不满足依赖关系 在注入点 [BackedAnnotatedField] @Inject private academy.learnprogramming.services.TodoService.LOG
我对注入的 EntityManager 有同样的错误
这些是我的 classes:
TodoService.class(我要测试的class)
package academy.learnprogramming.services;
import academy.learnprogramming.entities.Todo;
import org.apache.log4j.Logger;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.util.List;
@Transactional
public class TodoService {
@Inject
private Logger LOG = Logger.getLogger(TodoService.class);
@Inject
EntityManager entityManager;
public Todo createTodo(Todo todo) {
//Persist into db
entityManager.persist(todo);
return todo;
}
public Todo updateTodo(Todo todo) {
entityManager.merge(todo);
return todo;
}
@PostConstruct
private void init() {
LOG.info("Bean TodoService created");
}
public Todo findTodoById(Long id) {
return entityManager.find(Todo.class, id);
}
public List<Todo> getTodos(){
return entityManager.createQuery("SELECT t from Todo t", Todo.class).getResultList();
}
}
TodoServiceTest.class(用于测试的class)
package academy.learnprogramming.services;
import academy.learnprogramming.config.Producers;
import academy.learnprogramming.entities.Todo;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(Arquillian.class)
public class TodoServiceTest {
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(TodoService.class, Todo.class, Producers.class)
.addAsResource("persistence.xml", "META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void createTodo() {
}
@Test
public void updateTodo() {
}
@Test
public void findTodoById() {
}
@Test
public void getTodos() {
}
}
Producers.class(Class 用于将第 3 方库添加到 CDI)
package academy.learnprogramming.config;
import org.apache.log4j.Logger;
import org.dozer.DozerBeanMapper;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;
//If producers becomes complitated, split it in many classes, each for a single producer
public class Producers {
@Produces
@PersistenceContext
EntityManager entityManager;
@Produces
public Logger produceLogger(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
//Auto mapper
@Produces
public DozerBeanMapper produceDozenBeanMapper() {
DozerBeanMapper mapper = new DozerBeanMapper();
List<String> mappingFiles = new ArrayList();
mappingFiles.add("dozerJdk8Converters.xml");
mapper.setMappingFiles(mappingFiles);
return mapper;
}
}
四处寻找,我了解到可能的问题可能是:
- beans.xml 如果您不放置 bean-discovery-mode="all" 可能会出现问题,因为它不会扫描未注释的 bean,但我的 beans.xml 文件有 bean -发现模式=“全部”
- 注入到 TodoService 中的 Logger 和 EntityManager class 不能有生产者,但我有生产者 class
- 人们在为 TodoService、TodoServiceTest 和 Producers classes 导入 Logger class 的过程中可能会出错,例如在一个 org.apache.log4j.Logger 中导入=51=] 和 java util.logging.Logger 另一个,但我有所有 classes 导入 org.apache.log4j.Logger
如果我删除 @Inject 注释并使用 classes 中的记录器,它会起作用。
我还能尝试什么? 非常感谢您的宝贵时间。
如果您使用 WAR 文件,请尝试使用 WebArchive
@Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class)
.addClasses(TodoService.class, Todo.class, Producers.class)
.addAsResource("persistence.xml", "META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
删除 Logger.getLogger(TodoService.class);
将要实例化记录器的生产者。
@RequestScoped
@Transactional
public class TodoService {
@Inject
private Logger log;
@Inject
EntityManager entityManager;
public Todo createTodo(Todo todo) {
//Persist into db
entityManager.persist(todo);
return todo;
}
public Todo updateTodo(Todo todo) {
entityManager.merge(todo);
return todo;
}
@PostConstruct
private void init() {
log.info("Bean TodoService created");
}
public Todo findTodoById(Long id) {
return entityManager.find(Todo.class, id);
}
public List<Todo> getTodos(){
return entityManager.createQuery("SELECT t from Todo t", Todo.class).getResultList();
}