Wildfly Swarm中JNoSQL+MongoDB的Repository自动注入问题
我正尝试基于JNoSQL、MongoDB和Wildfly Swarm构建一个Hello World项目。目前使用@Inject注入DocumentCollectionManager能正常工作,但注入自定义的UserRepository却失败了。
注入代码
@Inject private DocumentCollectionManager entityManager; // 正常工作 @Inject @Database(DatabaseType.DOCUMENT) private UserRepository userRepository; // 无法工作!
生产者配置代码
@ApplicationScoped public class MongoProducer { private static final String DATABASE = "db"; @Inject @ConfigurationUnit(name = "document", fileName = "jnosql.yaml") private DocumentCollectionManagerFactory<MongoDBDocumentCollectionManager> entityManager; @Produces @Database(DatabaseType.DOCUMENT) public DocumentCollectionManager getManager() { return entityManager.get(DATABASE); } }
抛出的错误信息
2018-05-23 11:30:31,270 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC000001: Failed to start service jboss.deployment.unit."demo.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."demo.war".WeldStartService: Failed to start service at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1978) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type UserRepository with qualifiers @Database at injection point [BackedAnnotatedField] @Inject @Database private com.example.demo.rest.HelloWorldEndpoint.userRepository at com.example.demo.rest.HelloWorldEndpoint.userRepository(HelloWorldEndpoint.java:0) at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:362) at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:284) at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:137) at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:158) at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:501) at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:61) at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:59) at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:62) at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:55) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) at org.jboss.threads.JBossThread.run(JBossThread.java:320) 2018-05-23 11:30:31,278 ERROR [org.jboss.as.controller.management-operation] (main) WFLYCTL0013: Operation ("add") failed - address: (("deployment" => "demo.war")) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"demo.war\".WeldStartService" => "Failed to start service Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type UserRepository with qualifiers @Database at injection point [BackedAnnotatedField] @Inject @Database private com.example.demo.rest.HelloWorldEndpoint.userRepository at com.example.demo.rest.HelloWorldEndpoint.userRepository(HelloWorldEndpoint.java:0) "}} 2018-05-23 11:30:31,279 ERROR [org.jboss.as.server] (main) WFLYSRV0021: Deploy of deployment "demo.war" was rolled back with the following failure message: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"demo.war\".WeldStartService" => "Failed to start service Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type UserRepository with qualifiers @Database at injection point [BackedAnnotatedField] @Inject @Database private com.example.demo.rest.HelloWorldEndpoint.userRepository at com.example.demo.rest.HelloWorldEndpoint.userRepository(HelloWorldEndpoint.java:0) "}}
解决方案
JNoSQL的Repository是靠CDI扩展自动生成实现类的,你的问题核心就是这个扩展没正常工作或者配置不匹配,我给你梳理几个排查和解决步骤:
1. 先检查UserRepository的定义是否合规
你的UserRepository必须继承JNoSQL的Repository接口,还要加上@Repository注解,这是CDI扩展识别它的关键,示例如下:
@Repository @Database(DatabaseType.DOCUMENT) // 和注入点的限定符对应上 public interface UserRepository extends Repository<User, String> { // 自定义查询方法(可选) }
如果没加@Repository,JNoSQL根本不会为这个接口生成实现类,CDI自然找不到可注入的实例。
2. 确保Wildfly Swarm加载了JNoSQL的CDI扩展
Wildfly Swarm默认不会自动扫描第三方CDI扩展,你需要:
- 在Maven/Gradle依赖里添加JNoSQL的Artemis扩展包(比如
org.jnosql.artemis:artemis-document,版本要和你用的JNoSQL一致) - 如果是打包成war,要确保这些依赖被正确打包到
WEB-INF/lib目录下;如果是用uber jar方式,要确认Swarm的打包配置包含了这些依赖
3. 匹配注入点和Repository的限定符
你注入时用了@Database(DatabaseType.DOCUMENT),那你的UserRepository上也必须加上相同的@Database注解,这样CDI才能把生成的实现类和注入点匹配起来。或者也可以去掉注入点的@Database注解,只要Repository类型正确,CDI会自动匹配。
4. 验证jnosql.yaml配置文件
确保配置文件放在src/main/resources下,MongoDB的连接信息、数据库名称等配置正确——错误的配置会导致JNoSQL扩展初始化失败,自然无法生成Repository实现。
5. 检查Wildfly Swarm的部署配置
如果用了jboss-deployment-structure.xml,要确保里面包含了JNoSQL相关的模块;如果是用Swarm的fractions,确认添加了CDI相关的fraction(比如cdi),因为JNoSQL依赖CDI来工作。
按这几步排查下来,应该就能解决Repository注入失败的问题了。
内容的提问来源于stack exchange,提问作者Victor

