CDI 生产商未获得资格认证
CDI producer not recognized with qualifiers
我有一个包含 2 个模块的 EAR 应用程序。一个WEB和一个EJB模块。
EJB 模块中有几个服务被注入到 WEB 模块的 classes 中,工作正常。但有些服务需要基于用户上下文的配置,这只能在 WEB 模块中提供。于是尝试在WEB模块中添加生产者
结构如下所示:
app-ear
|
+- app-ejb
| |
| +- Service
| +- ServiceConnector
|
+- app-web
|
+- ServiceConnectorProducer
这是该代码的简化版本:
服务 class 将连接器注入:(EJB)
public class Service {
@Inject
private ServiceConnector connector;
}
连接器 class 将处理服务的连接:(EJB)
public class ServiceConnector {
private final Config config;
public ServiceConnector(final Config config) {
this.config = config;
}
}
ServiceConnector
的制作人:(网络)
public class ServiceConnectorProducer {
@Produces
public ServiceConnector produce(UserContext userCtx) {
// ... create config and set data from user context
return new ServiceConnector(config);
}
}
此时生产者在注入点未被识别,我得到一个未满足的依赖错误:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
即使容器加载了生产者,也会发生这种情况:
WELD-000106: Bean: Producer Method [ServiceConenctor] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConenctorProducer.produce(UserContext)]
当我通过添加默认构造函数使 ServiceConnector
可被容器发现时,我得到了一个不明确的依赖项错误:
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
Possible dependencies:
- Producer Method [ServiceConnector] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConnector.produce(UserContext)],
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]
之后我尝试了以下方法来解决不明确的依赖关系。
- (添加限定符)
- (使用 @Any
)
- (使用 @Vetoed
)
但是所有这些解决方案都会导致不满足的依赖错误。
WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @SessionService
at injection point [BackedAnnotatedField] @Inject @SessionService private Service.connector
at Service.connector(Service.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]
所以现在我不知道如何解决这个问题。如何让WEB模块生成ServiceConnector
?
您很可能观察到 Java EE 伞规范可见性限制。
EAR 中的某些存档(EAR/lib、EJB jar、WAR)可以查看和访问的内容有限制。 CDI 然后遵循相同的注入模式。
根据应用服务器对规范的解释方式,这些规则的实施可能会略有不同。现在,如果您不想阅读规范(谁喜欢,呃?;-)),那么您可以查看 那种总结,虽然不是详尽无遗。
即在您的情况下,WAR 文件可以访问 EJB 的内容,但反之则不行。
在 CDI 术语中,这意味着 EJB jar 没有 "see" 您那里的生产者方法。
至于你在制作 ServiceConnector
一个 bean 时看到的模棱两可的依赖异常 - 我不是 100% 确定没有复制器和一些调试的情况。这可能是 EAR 中验证方式的错误,也可能是有意为之,因为理论上从 WAR 存档中您可以看到两个 ServiceConnector
.
类型的 bean
至于如何解决这个问题——我能想到的一件事是 CDI 扩展,它(在 Weld 的解释中)跨越整个 EAR。因此,使用 CDI 扩展来注册 bean 可能对您有用 ,而不管是什么存档做的。如果你这样做,请查看 AfterBeanDiscovery
observer 并在那里注册 bean。
我有一个包含 2 个模块的 EAR 应用程序。一个WEB和一个EJB模块。
EJB 模块中有几个服务被注入到 WEB 模块的 classes 中,工作正常。但有些服务需要基于用户上下文的配置,这只能在 WEB 模块中提供。于是尝试在WEB模块中添加生产者
结构如下所示:
app-ear
|
+- app-ejb
| |
| +- Service
| +- ServiceConnector
|
+- app-web
|
+- ServiceConnectorProducer
这是该代码的简化版本:
服务 class 将连接器注入:(EJB)
public class Service {
@Inject
private ServiceConnector connector;
}
连接器 class 将处理服务的连接:(EJB)
public class ServiceConnector {
private final Config config;
public ServiceConnector(final Config config) {
this.config = config;
}
}
ServiceConnector
的制作人:(网络)
public class ServiceConnectorProducer {
@Produces
public ServiceConnector produce(UserContext userCtx) {
// ... create config and set data from user context
return new ServiceConnector(config);
}
}
此时生产者在注入点未被识别,我得到一个未满足的依赖错误:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
即使容器加载了生产者,也会发生这种情况:
WELD-000106: Bean: Producer Method [ServiceConenctor] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConenctorProducer.produce(UserContext)]
当我通过添加默认构造函数使 ServiceConnector
可被容器发现时,我得到了一个不明确的依赖项错误:
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
Possible dependencies:
- Producer Method [ServiceConnector] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConnector.produce(UserContext)],
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]
之后我尝试了以下方法来解决不明确的依赖关系。
- (添加限定符)
- (使用 @Any
)
- @Vetoed
)
但是所有这些解决方案都会导致不满足的依赖错误。
WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @SessionService
at injection point [BackedAnnotatedField] @Inject @SessionService private Service.connector
at Service.connector(Service.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]
所以现在我不知道如何解决这个问题。如何让WEB模块生成ServiceConnector
?
您很可能观察到 Java EE 伞规范可见性限制。 EAR 中的某些存档(EAR/lib、EJB jar、WAR)可以查看和访问的内容有限制。 CDI 然后遵循相同的注入模式。
根据应用服务器对规范的解释方式,这些规则的实施可能会略有不同。现在,如果您不想阅读规范(谁喜欢,呃?;-)),那么您可以查看
即在您的情况下,WAR 文件可以访问 EJB 的内容,但反之则不行。 在 CDI 术语中,这意味着 EJB jar 没有 "see" 您那里的生产者方法。
至于你在制作 ServiceConnector
一个 bean 时看到的模棱两可的依赖异常 - 我不是 100% 确定没有复制器和一些调试的情况。这可能是 EAR 中验证方式的错误,也可能是有意为之,因为理论上从 WAR 存档中您可以看到两个 ServiceConnector
.
至于如何解决这个问题——我能想到的一件事是 CDI 扩展,它(在 Weld 的解释中)跨越整个 EAR。因此,使用 CDI 扩展来注册 bean 可能对您有用 ,而不管是什么存档做的。如果你这样做,请查看 AfterBeanDiscovery
observer 并在那里注册 bean。