I am trying to wrap my head around something here: Injection only works on the first layer of my application, but then it stops and all @Inject annotated properties are null in the objects returned from my factory pattern implementation. I read a lot about people having problems with getting CDI to work with JAX-RS but this seems not to be my problem. I have the feeling that I am missing some annotations, or I don't see the wood in front of all the trees (as we say here) ;-)
Edit: Did a sample project with the code I posted here to double check. Now I realise that I over simplified: in fact I am using a Factory Pattern to obtain my service, which might interrupt the managed context. Please see the augmented example:
Let's go.
First Layer: JAX-RS Application, all good
@RequestScoped
@Path("/somePath/someResource")
public class SomeResource {
@Inject
ISomeServiceFactory someServiceFactory;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public SomeResponse someMethod(@PathParam("foo") final String foo) {
ISomeService myService = someServiceFactory.getService(ServiceCatalog.valueOf(foo)); // works, we jump in there!
myService.someMethod();
}
}
public enum ServiceCatalog {
STANDARD("standard"), ADVANCED("advanced"), FOO("foo");
// ...
}
The broken service factory that is selecting an implementation based of known parameter (Enum) values from the REST API Call:
public interface ISomeServiceFactory {
public ISomeService getService(ServiceCatalog serviceType);
}
@Stateless
public class SomeServiceFactory implements ISomeServiceFactory {
public ISomeService getService(ServiceCatalog serviceType) {
if(serviceType.equals(ServiceCatalog.FOO)) {
return new FooService(); // will break CDI context
} else if (...) {
// ...
} else {
return new DefaultService(); // will also break CDI context
}
}
}
Second Layer: Some EJB, trouble here
// Interface:
public interface ISomeService {
public void someMethod();
}
// Implementation:
@Stateless
public class SomeService implements ISomeService {
@Inject
private ISomeDao someDao; // this will be null !!!
@Override
public void someMethod() {
someDao.doSomething() // exception thrown as someDao == null
}
}
The Dao that is supposed to be injected
public interface ISomeDao {
public void someMethod();
}
@Stateless
public class SomeDao implements ISomeDao {
public void someMethod() {}
}
Now at runtime WebSphere Liberty tells me (among other bindings...) this:
com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime
I CNTR0167I: The server is binding the com.ISomeDao interface of the
SomeDao enterprise bean in the my.war module of the my application.
The binding location is: java:global/my/SomeDao!com.ISomeDao
I have a beans.xml:
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
It seems as if the new SomeService() breaks everything, could you advice on how to implement the factory in a way that enables CDI further down the road? Thanks.