3
votes

I have an .ear file with the standard lib directory.

I have a .jar file in that lib directory. It contains UserInfoManager, which is an interface. It contains (for these purposes) no other classes. It also contains a META-INF/beans.xml file.

I have another .jar file in that lib directory. It contains a class named UserInfoResource that is a JAX-RS resource class. That class has the following inside it:

@Inject
private UserInfoManager userManager;

Next, I have an EJB .jar file at the root of the .ear file. It contains a class named UserManagerBean that implements the UserInfoManager interface. This class is annotated with @Stateless and basically nothing else (thus making it a local stateless session bean exposed via its local business interface (UserInfoManager). This .jar file also has a META-INF/beans.xml file.

Next, I have a .war file with an Application class in it and nothing else. This serves as the "mounting point" for any and all JAX-RS resources discovered at deployment time present in the lib directory. I do not declare this Java EE 6 module as a CDI bean archive since it contains no beans.

This spec-compliant arrangement fails at deployment time. Weld (the CDI implementation in GlassFish 3.1.2) claims that the injection point detailed above cannot be satisfied, as there are no known implementations of UserInfoManager available to it.

When that injection point is annotated with @EJB instead, everything works fine.

How do I get CDI to inject a local stateless session bean reference into a JAX-RS resource that is present on the classpath?

Update: Because no matter how I look at this it seems like a specification violation, I have filed a bug with a testcase attached. I encourage readers to take a look and see if they can get it to work.

Update: The workaround is to make sure that your JAX-RS classes are not bean archives, but are annotated with @ManagedBean. In addition, the {{.war}} file that serves as their mount point must be a bean archive (must have a {{WEB-INF/beans.xml}} file). Some combination of these requirements is a CDI specification violation. The following bug tracks these issues: http://java.net/jira/browse/GLASSFISH-18793

1
Is UserInfoResource declared @RequestScoped?John Ament
Hello; no; I have not added any CDI annotations to UserInfoResource.Laird Nelson
I made the suggested change; there was no difference in the outcome.Laird Nelson
Do you have an application.xml defined in your ear? You mention locations of jar files and war files, but not how they're defined in the ear's application.xml.John Ament
Yes, I do (it is auto-generated by Maven at version 6). Without CDI injection, the JAX-RS resource and EJB work fine. I've filed a bug complete with test case here: java.net/jira/browse/GLASSFISH-18793 Please feel free to take a look.Laird Nelson

1 Answers

3
votes

Jersey does not treat Resources as managed beans unless there is an explicit scope/@ManagedBean annotation attached to it. So, you need to annotate your resource with @ManagedBean or @RequestScoped for the injection to work.

Seems the problem occurs only if beans.xml is included in the resource jar file. When I remove it and attach @ManagedBean annotation to the resource class (instead of @RequestScoped, since @RequestScoped does not work if no beans.xml is present) it works. I am not a CDI expert, so not sure if this is as designed or a bug.