Alex
Alex

Reputation: 1535

Jersey EJB injection

I read a lot about the possibility of injection with jax rs 2.0 and in particular with jersey.

I even read that ejb injection is expected in jax rs 2.0 spec. But i still haven't found a unique solution among the variety of posts i read over the net.

In my use case i'm working with:

WildFly 9.0 and Jersey 2.x

I have a webapplication exposing my REST services and importing a jar implementing my model data.

This is the CDI approach:

@RequestScoped 
@Path("/myPath")
public class ModelRetriever {

@Context
SecurityContext securityContext;

@Inject
private IMyModel MyModel;   

@Path("{i}")          
@GET 
@Produces("application/json")
public Response countries(@PathParam("i") String countryId) 
        throws JSONException, Failure, IOException {

    MyModel.doSomething();
}

This is my IMyModel interface

public interface IKasPrincipal extends Principal {
    public void doSomething();
}

And this is MyModel implementation:

@RequestScope
public class MyModelImpl implements IMyModel {

    public void doSomehting() {
        doSomething();
    }
}

Another method i tried is to use EJB injection changing my previous annotations like this:

@Stateless 
@Path("/myPath")
public class ModelRetriever {

@EJB
private IMyModel MyModel;   

@Path("{i}")          
@GET 
@Produces("application/json")
public Response countries(@PathParam("i") String countryId) 
        throws JSONException, Failure, IOException {

    MyModel.doSomething();
}

This is my IMyModel interface

@Local
public interface IKasPrincipal extends Principal {
    public void doSomething();
}

And this is MyModel implementation:

@Stateless
public class MyModelImpl implements IMyModel {

    public void doSomehting() {
        doSomething();
    }
} 

i get a null object using EJB approach and i get this exception using CDI

Caused by: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IMyModel,parent=ModelRetriever,qualifiers={},position=-1,optional=false,self=false,unqualified=null,616459318)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:211)
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:234)

So is there anything i'm missing?

Upvotes: 1

Views: 3464

Answers (2)

Filip
Filip

Reputation: 1068

see other Stack Overflow related posts:

Dependency injection with Jersey 2.0

HK2 Jersey EJB 3 injection

The problem you are having is that HK2 does not know about anything that was not registered directly into it, and HK2 tries to to satisfy all dependency in your Jersey aware class.

I has this issue a while back. Then I discovered that Jersey uses HK2 internally. HK2 is a JSR-330 implementation (CDI).

One would think that a open-source project would declares it's CDI beans and use them regardless of the CDI implementation, but it looks like its not that way.

see : https://java.net/jira/browse/JERSEY-1933

see : https://hk2.java.net/integration.html


You can register your components into HK2...

see : https://jersey.java.net/documentation/latest/ioc.html

For all I know, you cannot inject CDI components (or anything else, as EJB) into Jersey's classes using your own (or your container's) CDI implementation, unless you use Glassfish (which personally I would never use) which in turn uses HK2 as its CDI implementation.

To me, this is a major draw back. But the only(?) draw back of Jersey.

-Maybe I missed something (which is very possible)

-Maybe this is a trick from Oracle so that you can't use Jersey in, let's say, your Websphere app which uses OpenWeb Beans as CDI implementation.

-Maybe they hardwired it to HK2, and just don't care that Jersey can't be used as a drop in component in your application, which relies on CDI or EJB

Upvotes: 1

Jin Kwon
Jin Kwon

Reputation: 22027

I'm not aware of why @EJB not worked, but, you can use @Produces/@Disposes bean.

@ApplicationScoped // or some other scoped
public class MyModelProducer {

    @Produces public MyModel produceMyModel() {
    }

    public void disposeMyModel@Disposes final MyModel model) {
    }
}

Upvotes: 0

Related Questions