Search code examples
jakarta-eeejbwebspherecdi

Inject beans produced from a Websphere shared library into an EJB


I have an EJB session bean which injects Logger produced from a class which is packed in a jar file. The jar file is added to classpath.

package org.cdi.inject.test;

import javax.ejb.Stateless;
import javax.inject.Inject;

import org.apache.log4j.Logger;

@Stateless
public class MySessionBean{

  @Inject
  private Logger log;

}

The class which produces Logger looks like this:

package org.cdi.inject.producer;

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Singleton;

import org.apache.log4j.Logger;

@Singleton
public class LogProducer {

    @Produces
    public Logger getLogger(InjectionPoint ip){
        String declaringClass = ip.getMember().getDeclaringClass().getName();   
        return Logger.getLogger(declaringClass);
    }
}

Class MySessionBean is packed in and EJB jar file MyEjb.jar and class LogProducer is packed in bean-producer.jar. As mentioned here, both these jars contain a META-INF directory which contains beans.xml.

The server I'm using is Websphere 8.0. I've deployed MyEjb.jar directly through console and bean-producer.jar is added to a shared library. The shared library is added to classpath of ejb jar.

With the above configuration, injection fails with error :

[10/1/15 12:56:53:762 GMT+05:30] 00000037 InjectInjecti E   CWOWB0102E: A JCDI error has occurred: Api type [org.apache.log4j.Logger] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.Default()]
for injection into
 Field Injection Point, field :  private org.apache.log4j.Logger org.cdi.inject.producer.MySessionBean.log, Bean Owner : [1527619878,Name:null,WebBeans Type:MANAGED,API Types:[org.cdi.inject.producer.MySessionBean,java.lang.Object],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]]
         InjectionType   :  [class org.apache.log4j.Logger]
         Annotated       :  [Annotated Field,Base Type : class org.apache.log4j.Logger,Type Closures : [interface org.apache.log4j.spi.AppenderAttachable, class org.apache.log4j.Logger, class java.lang.Object, class org.apache.log4j.Category],Annotations : [@javax.inject.Inject()],Java Member Name : log]
         Qualifiers      :  [[@javax.enterprise.inject.Default()]]

at org.apache.webbeans.util.InjectionExceptionUtils.throwUnsatisfiedResolutionException(InjectionExceptionUtils.java:92)
... stacktrace truncated

However if I add LogProducer to MyEjb.jar, it works.


Solution

  • This is not possible. CDI only scans for producer annotations (and managed bean classes, etc.) in archives packaged in the application, not in shared libraries. This is similar to the restriction classes annotated @Stateless or @WebServlet must be packaged within the application.