glassfish
                                
                                 glassfish copied to clipboard
                                
                                    glassfish copied to clipboard
                            
                            
                            
                        Include org.glassfish.jersey.ext.cdi:jersey-cdi-rs-inject to support @Inject in Jaxrs
Environment Details
- GlassFish Version (and build number): Glassfish
- JDK version: 17
- OS: Windows
- Database: built-in Derby
Problem Description
I have tried to use @Inject to replace @Context in Jaxrs beans, all failed to works.
see: https://github.com/eclipse-ee4j/jersey/issues/5100
@Path("todos")
@RequestScoped
public class TodoResources {
    //@Inject
    @Context
    ResourceContext resourceContext;
    //@Inject
    @Context
    UriInfo uriInfo;
And I follow the new features in Rest 3.1 article to taste Jaxrs 3.1. https://dev.to/andymc12/what-s-coming-in-jakarta-rest-3-1-ole
Steps to reproduce
- Checkout my sample project, https://github.com/hantsy/jakartaee10-sandbox/tree/master/rest
- build and deploy to Glassfish
- If changing @Contextto@Injectin theTodoResources.java, all failed.
AFAIK, Jakarta REST 3.1 (EE 10) doesn't specify anything about injecting JAX-RS resources using @Inject yet, besides claiming that injection using @Context annotation is deprecated and it will be replaced by CDI's @Inject in the future. Usage of @Context annotation is deprecated without any suggested alternative yet. The Javadoc just says: "Note that future versions of this API will stop supporting injection via Context as part of a tighter integration and alignment with Jakarta CDI".
Therefore I don't think this is a bug, rather an enhancement request. It certainly would be nice to support this in GlassFish 7. Especially, since there is already support for it in Jersey with org.glassfish.jersey.ext.cdi:jersey-cdi-rs-inject as mentioned in comment here. This module is not included in GlassFish and never was, but it's probably easy to add it to GlassFish (although just dropping it into GlassFish module directory isn't enough)
It seems the latest Glassfish 7.0.0-M9 includes org.glassfish.jersey.ext.cdi:jersey-cdi-rs-inject, but I still encountered an issue when using @Inject UriInfo or @Inject ResourceContext.
According to the exception info, I added an extra @Any annotation, still failed.
    @Inject
    @Any
    ResourceContext resourceContext;
    @Inject
    @Any // or  @JaxRsContext
    UriInfo uriInfo;
The exception info like this.
Oct 01, 2022 10:04:20 AM org.jboss.arquillian.container.glassfish.clientutils.GlassFishClientUtil getResponseMap
SEVERE: exit_code: FAILURE, message: Error occurred during deployment: Exception while loading the app : CDI deployment failure:WELD-001408: Unsatisfied dependencies for type ResourceContext with qualifiers @Any
  at injection point [BackedAnnotatedField] @Inject @Any com.example.TodoResources.resourceContext
  at com.example.TodoResources.resourceContext(TodoResources.java:0)
. Please see server.log for more details. [status: CLIENT_ERROR reason: Bad Request]
Oct 01, 2022 10:04:20 AM org.jboss.arquillian.container.glassfish.clientutils.GlassFishClientUtil getResponseMap
WARNING: exit_code: FAILURE, message: Resource not found. [status: CLIENT_ERROR reason: Not Found]
The complete server log file, server.log
As I explained above, the specific jersey-cdi-rs-inject module isn't included in GlassFish, not even in 7.0.0-M9 . GlassFish 7.0.0-M9 uses components of Jersey 3.1.0-M8, but not specifically the jersey-cdi-rs-inject module.
Did you try with adding the jersey-cdi-rs-inject module into GlassFish? It's not bundled in GlassFish by default, so there's no way injecting works if this module isn't added to GlassFish. Maybe it's enough to add it to the application but I'm not sure if it's enough.
If adding the module into GlassFish works, we can add it to GlassFish by default, so that it works out of the box.
If I copy the jersey-cdi-rs-inject to the target Glassfish modules by dependency plugin.
<execution>
      <id>copy</id>
      <phase>pre-integration-test</phase>
      <goals>
          <goal>copy</goal>
      </goals>
      <configuration>
          <artifactItems>
              <artifactItem>
                  <groupId>org.glassfish.jersey.ext.cdi</groupId>
                  <artifactId>jersey-cdi-rs-inject</artifactId>
                  <version>${jersey.version}</version>
                  <type>jar</type>
                  <overWrite>false</overWrite>
              </artifactItem>
          </artifactItems>
          <outputDirectory>${project.build.directory}/glassfish7/glassfish/modules</outputDirectory>
      </configuration>
  </execution>
When running the TodoResourceTests will throw the following exception.
Oct 01, 2022 4:14:03 PM org.jboss.arquillian.container.glassfish.clientutils.GlassFishClientUtil getResponseMap
SEVERE: exit_code: FAILURE, message: Error occurred during deployment: Exception while loading the app : CDI definition failure:Exception List with 1 exceptions:
Exception 0 :
org.jboss.weld.exceptions.IllegalArgumentException: WELD-001325: No instance of an extension class org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider registered with the deployment
        at org.jboss.weld.manager.BeanManagerImpl.getExtension(BeanManagerImpl.java:1421)
        at org.jboss.weld.util.ForwardingBeanManager.getExtension(ForwardingBeanManager.java:228)
        at org.glassfish.jersey.ext.cdi1x.inject.internal.InjectExtension.beforeDiscoveryObserver(InjectExtension.java:70)
It looks like further integration is needed in GlassFish. I think the error means that the CDI extension CdiComponentProvider, which connects Jersey to the Bean Manager, isn't loaded. I'm not sure what is needed for that but I would start with the test project for CdiComponentProvider: https://github.com/eclipse-ee4j/jersey/blob/c5e71d03a02f0f79a3df451c4d325d90a5953542/tests/integration/cdi-integration/cdi-test-webapp/src/test/java/org/glassfish/jersey/tests/cdi/resources/CdiComponentProviderTest.java
Maybe @jansupol can clarify what's needed to integrate jersey-cdi-rs-inject into GlassFish/Weld.
Odd, we have the test working. Will try with M9.
Still working with M9. @hantsy I suspect there is some Jersey mismatch in your local env, I have seen the message in my env when there was no OSGi header in the module (3.1.0-M7)
I am using Glassfish 7.0.0.M9 and built-in Jersey, I am not sure if it is the newest version.
Odd, we have the test working. Will try with M9.
In your example project, it copies the latest jeyser libs to override the default ones.
In your example project, it copies the latest jeyser libs to override the default ones.
Yes, but arguably, they are the same as in the Glassfish. Also, I added
<properties>
        <jersey.version>3.1.0-M8</jersey.version>
So that Jersey M8 is there (exactly the same as in GF) and still works fine. But it was not clear what version of jersey-cdi-rs-inject you are using, the error message you have  I got with M7, not with M8.
I used Jersey 3.1.0-M8, https://github.com/hantsy/jakartaee10-sandbox/blob/master/pom.xml#L40
I am sure it does not work till GF7 M9 when using the original Glassfish(of course copy the jersey-cdi-rs-inject to glassfish modules folder) without overriding the built-in Jersey libs.
Yes, your test intermittently fails, as the CDI extensions are processed in a random order. For some reason that is not happening our example. That can be fixed. Another issue is more severe, though: The Jakarta REST Spec, Section 11 says:
A Servlet-based implementation MUST support injection of the following Servlet-defined types: ServletConfig , ServletContext , HttpServletRequest and HttpServletResponse .
But when we start providing CDI bean for HttpServletRequest, we get messed up with Krazo, which also provides a bean for injecting HttpServletRequest, and there is the CDI ambiguity:
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type HttpServletRequest with qualifiers @Default at injection point [UnbackedAnnotatedField] @Inject private org.eclipse.krazo.cdi.RedirectScopeManager.request at org.eclipse.krazo.cdi.RedirectScopeManager.request(RedirectScopeManager.java:0) Possible dependencies:
- WELD%AbstractBuiltInBean%org.eclipse.krazo.cdi.KrazoCdiExtension%HttpServletRequest,
- org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$Hk2Bean@1c10d8ce
Thinking about it, the HttpServletRequest bean should be provided by the Servlet implementation. Jakarta REST implementation should not provide @Default bean, but the Spec requests so. This should have been fixed in the the Jakarta REST 4.0, I believe.
Thinking about it, the HttpServletRequest bean should be provided by the Servlet implementation.
Indeed. All other specs should not provide this, unless they provide a special decorated version or so. Let's make sure we get this into the next revision of the Servlet spec (in an optional Jakarta EE environment section, so Greg and Tomcat don't have to worry about this).
So, how to get it work in the current M9?
Jersey 3.1.0 Final has been released. That should have been working fine.
Yes, hope the next GlassFish release will include it.