替代 CDI 实现 - WELD-001408:不满足类型存储库与限定符 @Default 的依赖关系
Alternative CDI implementation - WELD-001408: Unsatisfied dependencies for type Repository with qualifiers @Default
我有一个接口 Repository
,有两个实现,DBRepository
和 UTRepository
。 UTRepository
用 @Alternative
注释,我正在尝试在 JUnit 测试中使用它。
测试class:
@RunWith(Arquillian.class)
public class UserServiceTest {
@Inject
private UserService service;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(Repository.class, UserService.class, UTRepository.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void addCharacterTest() {
service.addCharacter(1L, Mockito.mock(GameCharacter.class));
}
}
正在测试的class:
public class UserService {
@Inject
Repository repository;
@Transactional
public void addCharacter(Long userId, GameCharacter character) {
User user = repository.readById(userId, User.class);
user.addCharacter(character);
repository.update(user);
}
}
我的beans.xml
文件(放在src/test/webapp/WEB-INF/beans.xml):
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_2.xsd"
bean-discovery-mode="all">
<alternatives>
<class>org.package.name.UTRepository</class>
</alternatives>
</beans>
当我尝试 运行 测试时,出现异常:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Repository with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject org.package.name.services.UserService.repository
at org.package.name.services.UserService.repository(UserService.java:0)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:63)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:56)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
有什么问题?
问题似乎出在 .addAsManifestResource
参数上。我必须将 StringAsset
与 Arquillian 将添加到 beans.xml 的替代项一起使用,而不是空实例。
现在是createDeployment()
方法:
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(Repository.class, UserService.class, UTRepository.class)
.addAsManifestResource(new StringAsset("<alternatives><class>org.package.name.repositories.UTRepository</class></alternatives>"), "beans.xml");
}
您找到的解决方案效果很好,所以只是为了完整。
基本上您需要添加 beans.xml
来启用您的替代方案。 EmptyAsset.INSTANCE
将导致空 beans.xml 在这种情况下不会削减它。
但是,在您的解决方案中,您放置在 src/test/webapp/WEB-INF/beans.xml
下的 beans.xml
没有任何作用。 如果您想利用现有的 beans.xml
文件,您可以使用:
addAsManifestResource(File resource, String target)
添加给定 File
与名称 target
addAsManifestResource(Package resourcePackage, String resourceName, String target)
这允许您仅指定文件所在的包,然后是它的名称和文件名称,您希望它在部署中使用
我有一个接口 Repository
,有两个实现,DBRepository
和 UTRepository
。 UTRepository
用 @Alternative
注释,我正在尝试在 JUnit 测试中使用它。
测试class:
@RunWith(Arquillian.class)
public class UserServiceTest {
@Inject
private UserService service;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(Repository.class, UserService.class, UTRepository.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void addCharacterTest() {
service.addCharacter(1L, Mockito.mock(GameCharacter.class));
}
}
正在测试的class:
public class UserService {
@Inject
Repository repository;
@Transactional
public void addCharacter(Long userId, GameCharacter character) {
User user = repository.readById(userId, User.class);
user.addCharacter(character);
repository.update(user);
}
}
我的beans.xml
文件(放在src/test/webapp/WEB-INF/beans.xml):
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_2.xsd"
bean-discovery-mode="all">
<alternatives>
<class>org.package.name.UTRepository</class>
</alternatives>
</beans>
当我尝试 运行 测试时,出现异常:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Repository with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject org.package.name.services.UserService.repository
at org.package.name.services.UserService.repository(UserService.java:0)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:63)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:56)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
有什么问题?
问题似乎出在 .addAsManifestResource
参数上。我必须将 StringAsset
与 Arquillian 将添加到 beans.xml 的替代项一起使用,而不是空实例。
现在是createDeployment()
方法:
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(Repository.class, UserService.class, UTRepository.class)
.addAsManifestResource(new StringAsset("<alternatives><class>org.package.name.repositories.UTRepository</class></alternatives>"), "beans.xml");
}
您找到的解决方案效果很好,所以只是为了完整。
基本上您需要添加 beans.xml
来启用您的替代方案。 EmptyAsset.INSTANCE
将导致空 beans.xml 在这种情况下不会削减它。
但是,在您的解决方案中,您放置在 src/test/webapp/WEB-INF/beans.xml
下的 beans.xml
没有任何作用。 如果您想利用现有的 beans.xml
文件,您可以使用:
addAsManifestResource(File resource, String target)
添加给定File
与名称target
addAsManifestResource(Package resourcePackage, String resourceName, String target)
这允许您仅指定文件所在的包,然后是它的名称和文件名称,您希望它在部署中使用