WELD-001408: Ketergantungan tidak terpenuhi untuk tipe Logger dengan kualifikasi @Default pada titik injeksi [BackedAnnotatedField] @Inject
Saya mengalami masalah ini saat menguji aplikasi JavaEE8 dengan Arquillian: WELD-001408: Dependensi yang tidak terpenuhi untuk tipe Logger dengan kualifikasi @Default pada titik injeksi [BackedAnnotatedField] @Inject private academy.learnprogramming.services.TodoService.LOG
Saya memiliki kesalahan yang sama untuk EntityManager yang diinjeksi
Ini adalah kelas saya:
TodoService.class (kelas yang harus saya uji)
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 (Kelas yang digunakan untuk pengujian)
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 (Kelas yang digunakan untuk menambahkan perpustakaan pihak ketiga ke 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;
}
}
Mencari-cari, saya mengerti bahwa kemungkinan masalah bisa jadi:
- beans.xml dapat memberikan masalah jika Anda tidak meletakkan bean-discovery-mode = "all", karena tidak akan memindai kacang yang tidak dianotasi, tetapi file beans.xml saya memiliki bean-discovery-mode = "all"
- Logger dan EntityManager yang dimasukkan ke dalam kelas TodoService tidak dapat memiliki Produser, tetapi saya memiliki kelas Produser
- Orang dapat membuat kesalahan selama pengimporan kelas Logger untuk kelas TodoService, TodoServiceTest dan Producers, misalnya dengan mengimpor org.apache.log4j.Logger dalam satu kelas, dan java util.logging.Logger untuk kelas lainnya, tetapi saya memiliki semua kelas dengan impor org.apache.log4j.Logger
Jika saya menghapus anotasi @Inject dan saya menggunakan logger dari kelas, itu berhasil.
Apa lagi yang bisa saya coba? Terima kasih banyak atas waktunya.
Jawaban
Coba gunakan WebArchive jika Anda menggunakan file WAR
@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");
}
hapus Logger.getLogger(TodoService.class);
produser yang akan digunakan untuk membuat logger.
@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();
}