Java 将bean注入EJB,EJB已在另一个模块WAR中实现
我的结构如下:Java 将bean注入EJB,EJB已在另一个模块WAR中实现,java,jakarta-ee,ejb,cdi,Java,Jakarta Ee,Ejb,Cdi,我的结构如下: EAR | | - EJB | - WAR (servlet) | - JAR (api) JAR包含几个接口和限定符。这些接口和限定符将用于其他模块——WAR和EJB WAR将JAR作为一个依赖项,一个类实现一个特定的接口。该类用限定符进行注释。接口和限定符都来自JAR EJB将JAR作为依赖项,我希望它能够注入WAR实现的bean 但它不起作用。错误崩溃: 原因:org.jboss.weld.exceptions.WeldException:weld-001602: 无法为
EAR
|
| - EJB
| - WAR (servlet)
| - JAR (api)
JAR包含几个接口和限定符。这些接口和限定符将用于其他模块——WAR和EJB
WAR将JAR作为一个依赖项,一个类实现一个特定的接口。该类用限定符进行注释。接口和限定符都来自JAR
EJB将JAR作为依赖项,我希望它能够注入WAR实现的bean
但它不起作用。错误崩溃:
原因:org.jboss.weld.exceptions.WeldException:weld-001602:
无法为创建限定符实例模型
@com.api.QualifierWithParams()
同样,@com.api.QualifierWithParams()来自已导入的JAR
我假设运行时不知道模块之间的CDIBean
现在我这么做的全部原因是因为EJB可以是@Singleton,它将被任何数量的servlet实例访问。像缓存一样使用它。我想我可以复制一些代码,但不是。有办法吗
编辑-我花了一段时间来删除代码,但它是:
/*
EJB:
In maven this will have in its pom.xml's dependencies a dependency element for the JAR below.
*/
@Local
public interface EJBInterface {
public String someBusinessMethod (String s);
}
@Singleton(name="EBJImplementation")
@javax.ejb.Startup
@Local(EJBInterface.class)
public class EBJImplementation implements EJBInterface{
@javax.inject.Inject @com.api.QualifierWithParams(type=SomeType.PRIMARY, someQualifierParameter=15) InjectableBeanInterface b;
@Override
public String someBusinessMethod (String s){
return s + " with param value of: " + Integer.parseInt(b.getParam());
}
/*
@PostConstruct
private void setUp(){
}
*/
}
////////////////////////////////////////////
JAR:
package com.api;
public interface InjectableBeanInterface {
public int getParam();
}
package com.api;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface QualifierWithParams {
SomeType type() default SomeType.PRIMARY; //just an enum to help reduce annotation explosion
@Nonbinding int someQualifierParameter() default 0;
}
////////////////////////////////////////////
/*
WAR:
Like the EJB, it will include JAR file as a dependency
*/
public class BeanImpl implements com.api.InjectableBeanInterface{
private int someQualifierParameter;
public BeanImpl (int p){
someQualifierParameter = p;
}
@Override
public int getParam(){return someQualifierParameter == null ? -1 : someQualifierParameter;}
}
public class InjectableBeanFactory {
@Produces
@com.api.QualifierWithParams(type=SomeType.PRIMARY)
public com.api.InjectableBeanInterface productionFact(InjectionPoint ip){
//get the parameter from the qualifier and create new instance
Annotated a = ip.getAnnotated();
com.api.QualifierWithParams qualifierParams = a.getAnnotation(com.api.QualifierWithParams.class);
int tempParam = qualifierParams.someQualifierParameter();
return new BeanImpl(tempParam);
}
}
//Servlet. Configuration is done in the web.xml . This is the entry point of the application.
public class Main extends HttpServlet{
private @EJB EJBInterface b;
@Override
protected void doGet(HttpServletRequest rq, HttpServletResponse rs) throws ServletException, IOException {
Logger.getLogger("main-logger").log(Level.INFO, b.someBusinessMethod("called from servlet"));
//...
}
}
堆栈跟踪:
Failed to start service jboss.deployment.unit."test.ear".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."test".WeldStartService: Failed to start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.jboss.weld.exceptions.WeldException: WELD-001602: Cannot create qualifier instance model for @com.api.QualifierWithParams(type=PRIMARY, someQualifierParameter=15)
at com.api.QualifierWithParams.type(QualifierWithParams.java:0)
StackTrace:
at org.jboss.weld.resolution.QualifierInstance.createValues(QualifierInstance.java:139)
at org.jboss.weld.resolution.QualifierInstance.of(QualifierInstance.java:96)
at org.jboss.weld.resolution.ResolvableBuilder.addQualifier(ResolvableBuilder.java:147)
at org.jboss.weld.resolution.ResolvableBuilder.addQualifiers(ResolvableBuilder.java:197)
at org.jboss.weld.resolution.ResolvableBuilder.<init>(ResolvableBuilder.java:83)
at org.jboss.weld.manager.BeanManagerImpl.getBeans(BeanManagerImpl.java:567)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:357)
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$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.weld.resolution.QualifierInstance.createValues(QualifierInstance.java:137)
... 19 more
无法启动服务jboss.deployment.unit.“test.ear”。服务jboss.deployment.unit.“test”中的WeldStartService:org.jboss.msc.service.StartException。WeldStartService:无法启动服务
位于org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
运行(Thread.java:748)
原因:org.jboss.weld.exceptions.WeldException:weld-001602:无法为@com.api.QualifierWithParams(type=PRIMARY,someQualifierParameter=15)创建限定符实例模型
位于com.api.QualifierWithParams.type(QualifierWithParams.java:0)
堆栈跟踪:
位于org.jboss.weld.resolution.QualifierInstance.createValues(QualifierInstance.java:139)
位于org.jboss.weld.resolution.QualifierInstance.of(QualifierInstance.java:96)
位于org.jboss.weld.resolution.ResolvableBuilder.addQualifier(ResolvableBuilder.java:147)
位于org.jboss.weld.resolution.ResolvableBuilder.addQualifiers(ResolvableBuilder.java:197)
位于org.jboss.weld.resolution.ResolvableBuilder(ResolvableBuilder.java:83)
位于org.jboss.weld.manager.BeanManagerImpl.getBeans(BeanManagerImpl.java:567)
位于org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:357)
在org.jboss.weld.bootstrap.Validator.validateInjectionPoint上(Validator.java:281)
位于org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
位于org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
位于org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
位于org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
位于org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
在org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
在org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
在java.util.concurrent.FutureTask.run(FutureTask.java:266)处
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
运行(Thread.java:748)
位于org.jboss.threads.JBossThread.run(JBossThread.java:320)
原因:java.lang.IllegalArgumentException:对象不是声明类的实例
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.jboss.weld.resolution.QualifierInstance.createValues(QualifierInstance.java:137)
... 还有19个
进一步的测试表明,如果我将其作为实例注入,它将工作:
@Inject @Any javax.enterprise.inject.Instance<InjectableBeanInterface> d;
必须手动实现限定符(QualifierWithParams):
public class QualifierWithParamsIMPL extends AnnotationLiteral<QualifierWithParams> implements QualifierWithParams {
private final SomeType type;
private final int someQualifierParameter;
public CMSdbConnectionIMPL(SomeType type, int someQualifierParameter){
this.type = type;
this.someQualifierParameter = someQualifierParameter;
}
@Override
public String type() {return type;}
@Override
public String someQualifierParameter() {return someQualifierParameter;}
}
将为空
所以我想我会研究其他的方法。我可能会使用@ApplicationScoped CDIBean来代替@Singleton EJB。show codeplease@NkosieMaphumuloOP已用代码编辑。您引用的异常是否有由…引起的后续
?如果是,请添加完整的堆栈trace@SteveC是的,有:“原因:java.lang.IllegalArgumentException:对象不是声明类的实例”。使用堆栈跟踪更新了OP。基本上它说它找不到对象,因为它是另一个模块中的另一个类?
public class QualifierWithParamsIMPL extends AnnotationLiteral<QualifierWithParams> implements QualifierWithParams {
private final SomeType type;
private final int someQualifierParameter;
public CMSdbConnectionIMPL(SomeType type, int someQualifierParameter){
this.type = type;
this.someQualifierParameter = someQualifierParameter;
}
@Override
public String type() {return type;}
@Override
public String someQualifierParameter() {return someQualifierParameter;}
}
com.api.QualifierWithParams qualifierParams = a.getAnnotation(com.api.QualifierWithParams.class);