Sri
Sri

Reputation: 4853

Injecting EJB Bean using CDI

I'm trying to inject a EJB singleton bean into a CDI bean using @Inject. But the injected instance is sometime local and sometime it's remote instance (changes over restart). It's not consistent.

In the following sample, the TestService ejb's remote instance is injected into the GetTestData cdi managed bean. But I'm expecting the local instance. And it's also not consistent, sometimes it injects the local instance. I've figured out that by printing the injected bean in GetTestData class.

As a note, my test classes are excluded in the deployment package.

Any idea how to make it consistently inject local instance?

EJB Singleton Bean:

@Singleton
@Local(TestService.class)
@Remote(TestServiceRemote.class)
public class TestServiceImpl implements TestService {
    ..
}

CDI Bean:

public class GetTestData {

    @Inject
    TestService testService;

    ....
}

Unit Test:

@RunWith(CdiRunner.class)
public class GetTestDataTest {

    @Inject
    private GetTestData getTestData;

    @Produces
    @ProducesAlternative
    @Mock
    private TestService testService;

    .....
}

I'm using JBoss 7.1.1-Final version (Application Server) and the Weld core version is 1.1.23-Final.

I'm not able to use @EJB because I'm using cdi-unit for testing.

Upvotes: 3

Views: 5641

Answers (1)

Antoine Sabot-Durand
Antoine Sabot-Durand

Reputation: 4980

First, keep in mind that CDI injection doesn't support remote EJB out of the box (thru @Inject annotation). When using an EJB as a CDI bean, it's remote interface is excluded from the set of type for the bean as stated here. To be able to use a remote EJB you'll have to declare it as a resource like this.

public class ResourceProducers {

@Produces @EJB(ejbLink="../their.jar#TestServiceRemote")
TestServiceRemote remoteService;

}

So the behaviour you're experiencing probably comes from a CDI-unit since it is impossible that CDI use a remote EJB interface in an injection point.

My advice:

  1. Ask yourself if you really need EJB remote in your application. Today with JAX-RS and other techno like websocket they are a bit old fashioned.
  2. If you don't need EJB remote, add the EJB support annotation to your CDI-Unit test, it'll probably help the framework to give you the expected EJB behaviour (singleton). Also don't mock the EJB like you did : I don't think CDI-Unit will replicate EJB nature in your mock.
  3. If you want to stick with EJB remote, I guess you'll have to switch to a more strong test framework like Arquillian. I'm not a CDI-Unit specialist but I don't think they support remote EJB.
  4. If you're starting a development, you really should consider using WildFly application server, the next generation of JBoss server. You'll get Java EE 7 and more robust server.

Upvotes: 4

Related Questions