1

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.

Community
  • 1
  • 1
ares
  • 4,283
  • 6
  • 32
  • 63

1 Answers1

2

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.

Brett Kail
  • 33,593
  • 2
  • 85
  • 90
  • I kind of figured that out so I packaged both EJB and the producer jar into same ear and injection worked. But I've another problem, I'm getting `CWOWB0102E: A JCDI error has occurred: WebBeans context with scope type annotation @Singleton does not exist within current thread` – ares Oct 01 '15 at 15:30
  • @ares I would suggest accepting the answer and creating a new question for your new problem. My best guess is you're using a non-EE thread, or you've found a bug in WebSphere. – Brett Kail Oct 01 '15 at 16:22
  • on second thought, isn't the point of having a shared library is eliminating the need to pack jars which are shared by many applications into their specific EAR? – ares Oct 04 '15 at 17:56
  • @ares Yes, that's the point, but it's simply not supported for all scenarios, particularly those where the EE specs require the classes be in the EAR. – Brett Kail Oct 04 '15 at 20:12