WELD-001408: Enjeksiyon noktasında @Default niteleyicileriyle Logger türü için tatmin edilmeyen bağımlılıklar [BackedAnnotatedField] @Inject
Arquillian ile bir JavaEE8 uygulamasını test ederken bu sorunu yaşıyorum: WELD-001408: Enjeksiyon noktasında @ Default niteleyicileriyle Logger türü için tatminsiz bağımlılıklar [BackedAnnotatedField] @Inject private academy.learnprogramming.services.TodoService.LOG
Enjekte edilen EntityManager için aynı hatayı görüyorum
Bunlar benim derslerim:
TodoService.class (test etmem gereken sınıf)
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 (Test için kullanılan sınıf)
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 (CDI'ya 3. taraf kitaplıkları eklemek için kullanılan sınıf)
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;
}
}
Etrafı araştırırken, olası sorunların şunlar olabileceğini anladım:
- fasulye.xml, bean-discovery-mode = "all" koymazsanız sorun yaratabilir, çünkü açıklamalı olmayan çekirdekleri taramaz, ancak fasulye.xml dosyamda bean-discovery-mode = "all"
- TodoService sınıfına enjekte edilen Logger ve EntityManager bir Producer'a sahip olamazdı, ancak benim Producers sınıfım var
- TodoService, TodoServiceTest ve Producers sınıfları için Logger sınıfının içe aktarılması sırasında insanlar hata yapabilirler, örneğin bir sınıfta org.apache.log4j.Logger ve başka bir sınıfta java util.logging.Logger olabilir, ancak tüm sınıfları içe aktarım var org.apache.log4j.Logger
@Inject açıklamasını kaldırırsam ve günlükçüyü sınıflardan kullanırsam çalışır.
Başka ne deneyebilirim? Zaman ayırdığınız için çok teşekkür ederim.
Yanıtlar
WAR dosyası kullanıyorsanız WebArchive'ı kullanmayı deneyin
@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);
üreticiyi kaldırın, kaydediciyi somutlaştıracak.
@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();
}