Java – @EJB inject from different jar

ejbjavajboss

I'm trying to inject a bean located in a different jar file then the bean i'm trying to inject it into. Both beans are just basic @Stateless beans with local and remote interfaces.
If i use the normal injection

@EJB
IBean injectedBean;

or

@EJB
IBeanLocal injectedBean;

i get a NullPointerException when deploying the application.

If i use:

@EJB(mappedName="Bean")
IBean injectedBean;

or

@EJB(mappedName="Bean")
IBeanLocal injectedBean;

everything works and JBoss throws no deployment errors.

I might mention i use JBoss 5.

The bean class i'm injecting is declared as:

@Remote
public interface IBean

@Local
public interface IBeanLocal extends IBean

@Stateless(name = "Bean")
public class Bean implements IBean, IBeanLocal

My problem is that as specified in the documentation the mappedName property is vendor-specific. Is there any other way i could get this to work?

SOLVED:

I managed to solve the problem.

The problem was that i tried to deploy both jars individually which meant that each would get it's own ClassLoader in JBoss so that they couldn't find each other and would return a NullPointerException when trying to inject the bean.

The sollution was to add the jars to an ear and add an META-INF containing an application.xml looking like this:

<application xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"
         version="1.4">

  <display-name>Simple example of application</display-name>

  <module>
    <ejb>ejb1.jar</ejb>
  </module>
  <module>
    <ejb>ejb2.jar</ejb>
  </module>
</application>

I also had to change some JNDI lookups i made to match the new structure by adding the ear name before the classes: "ear-name/bean"

After this i just added the jars to the ear and everything deployed nicely.

Best Answer

You need to declare the local interface in order to have JBoss find the bean based on the interface only (assuming you're using EJB 3.0):

@Stateless(name = "Bean")
@Local ( IBeanLocal.class  )
@Remote ( IBean.class )
public class Bean implements IBean, IBeanLocal { ... }

Edit: IBean is a remote interface (see comment).

Related Topic