2017-06-10 9 views
0

Iは、以下の構造を有する:は異なるモジュールに実装されたEJBへ豆を注入 - WAR

EAR 
| 
| - EJB 
| - WAR (servlet) 
| - JAR (api) 

JARは、いくつかのインターフェースと修飾子を含んでいます。これらのインタフェースと修飾子は、他のモジュール(WARとEJB)で使用されます。

WARにはJARが依存関係にあり、クラスによって特定のインターフェイスが実装されています。そのクラスには修飾子が付いています。両方 - インタフェースと修飾子はJARから来ます。

EJBはJARを依存関係として持っており、WARが実装したBeanを注入できるようにしたいと考えています。

しかし、動作しません。エラーでクラッシュ:再び

Caused by: org.jboss.weld.exceptions.WeldException: WELD-001602: Cannot create qualifier instance model for @com.api.QualifierWithParams()

、com.api.QualifierWithParams @()が輸入されたJAR、から来ています。

私はランタイムがモジュール間のcdi beanを認識していないと思いますか?

私がこれをやっている理由は、EJBが@Singletonになり、サーブレットのインスタンス数が何であれアクセスできるからです。それをキャッシュのように並べ替えます。私はいくつかのコードを複製することができますが、むしろそうではないと思います。方法はありますか?

はEDIT - コードを下に取り除くために私にしばらく時間がかかったが、ここでは、次のとおりです。

/* 
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 
+0

コードを表示してください –

+0

@NkosieMaphumulo OPコードで編集してください。 – hrs

+0

あなたが引用した例外には、後続の「原因...」がありますか?もしそうなら、完全なスタックトレースを追加してください。 –

答えて

0

さらなる試験があったこと、私はインスタンスとして、それを注入した場合、それ動作します:

@Inject @Any javax.enterprise.inject.Instance<InjectableBeanInterface> d; 

しかし、私は手動で修飾子を追加する必要があります。

修飾子(QualifierWithParams)自体は手動で実装する必要があります
d.select(new QualifierWithParamsIMPL(SomeType.PRIMARY, 15)).get(); 

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;} 
} 

しかし、それはそうOPのコードでは、InjectionPointでこれは動作しません:

com.api.QualifierWithParams qualifierParams = a.getAnnotation(com.api.QualifierWithParams.class); 

を意志ヌル...

私は別の方法を検討すると思います。 @ Singleton EJBの代わりに@ApplicationScoped CDI Beanを実行します。

関連する問題