7

I'm trying to updating my Jersey project from 2.25 to 2.27.

Jersey is part of Java EE 8 since version 2.26, so I've also decided to update my project from Java EE 7 to Java EE 8, and from JAX-RS 2.0/CDI 1.x/Weld2.x/Apache Tomcat 8 to JAX-RS 2.1/CDI 2.0/Weld 3.0/Apache Tomcat 9.

The problem is I can't figure out the exact dependencies I need to include in my project (Maven project, pom.xml).

Things that I've tried:

  • I've followed intructions on this answer to install Weld on Tomcat
  • The latest Jersey documentation doesn't seem to cover this case. Anyway, I've tried to mimic the dependencies included in the CDI webapp example
  • Weld 2.4 to 3.0 migration guide
  • ...and finally, in my despair, different combinations of the following dependencies: cdi-api, jersey-hk2, javax.inject, jersey-cdi1x, jersey-cdi1x-servlet, weld-servlet, weld-servlet-core, weld-servlet-shaded, weld-core-impl

These are my current dependencies (pom.xml):

<!-- Java EE  -->
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>${java-ee.version}</version>
</dependency>

<!-- JAX-RS -->
<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>${jaxrs.version}</version>
</dependency>

<!-- Jersey -->
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>${jersey.version}</version>
</dependency>

<!--  CDI (Jersey HK2 / Weld) -->
<dependency>
    <groupId>org.glassfish.jersey.inject</groupId>
    <artifactId>jersey-hk2</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-shaded</artifactId>
    <version>${weld.version}</version>
</dependency>
<dependency>
    <groupId>org.jboss.weld</groupId>
    <artifactId>weld-core-impl</artifactId>
    <version>${weld.version}</version>
</dependency>

And this is the error I'm currently getting when trying to inject a @Singleton into my resource (@Path):

ADVERTENCIA: The following warnings have been detected: WARNING: Unknown HK2 failure detected:

...

GRAVE: El Servlet.service() para el servlet [CGERestApplication] en el contexto con ruta [/igea-cge-interfaces] lanzó la excepción [A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=SapClient,parent=CambioEstadoTrabajoService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,363959695)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of es.indra.isl.igea.external.cge.web.api.services.sap.CambioEstadoTrabajoService errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on es.indra.isl.igea.external.cge.web.api.services.sap.CambioEstadoTrabajoService
] with root cause:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=SapClient,parent=CambioEstadoTrabajoService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,363959695)
    at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
    at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:212)
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:235)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:358)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
    at org.glassfish.jersey.inject.hk2.RequestContext.findOrCreate(RequestContext.java:83)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2126)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:777)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:740)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:710)
    at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.getInstance(AbstractHk2InjectionManager.java:184)
    at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.getInstance(ImmediateHk2InjectionManager.java:54)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:129)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:75)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:110)

And the Tomcat startup log:

jun 04, 2018 10:09:07 AM org.jboss.weld.environment.servlet.EnhancedListener onStartup
INFO: WELD-ENV-001008: Initialize Weld using ServletContainerInitializer
jun 04, 2018 10:09:08 AM org.jboss.weld.bootstrap.WeldStartup 
INFO: WELD-000900: 3.0.4 (Final)
jun 04, 2018 10:09:08 AM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
jun 04, 2018 10:09:09 AM org.jboss.weld.environment.tomcat.TomcatContainer initialize
INFO: WELD-ENV-001100: Tomcat 7+ detected, CDI injection will be available in Servlets, Filters and Listeners.
Raúl Ríos
  • 71
  • 1
  • 6

2 Answers2

0

After some more research, I've found that the dependencies I listed in my question were right.

The one thing I was missing was to register an AbstractBinder in my ResourceConfig, as stated in this answer and in the Jersey user guide.

Example:

public class MyApplication extends ResourceConfig {

    public MyApplication() { 
        super();    

        // ...

        register(new MyInjectionBinder());
    }
}


@Singleton
public class MyInjectable {
    // ...
}


public class MyInjectionBinder extends AbstractBinder {

    @Override
    protected void configure() {
        bind(MyInjectable.class).to(MyInjectable.class).in(Singleton.class);
    }
}


@Path("/myresource")    
public class MyResource {

    @Inject
    MyInjectable injectable;

    // ...

}

Also note that if you want to inject other injectables into your injectable, they will not be available until the postconstruct lifecycle event:

@Singleton
public class MyInjectable {

    @Inject
    OtherInjectable other;

    @PostConstruct
    private void init() {   

        // ... do something with "other"
    }

}
Raúl Ríos
  • 71
  • 1
  • 6
  • I would appreciate an example here. I've tried visiting those links but I fail to see how I can bridge HK-2 and WELD without manually defining all bindings. – matsa Sep 18 '18 at 12:20
  • Example added as requested by @matsa – Raúl Ríos Sep 27 '18 at 11:27
  • Isn't it just use HK2 instead of Weld/CDI? It works by default in Jersey with `AbstractBinder` without any annotation except `@Inject`, because Jersey uses HK2 for injection and this `AbstractBinder` just configures HK2's ServiceLocator. – Ruslan Stelmachenko Dec 10 '18 at 22:56
  • For me it works without the `AbstractBinder` by simply adding the `jersey-cdi1x` dependency which still seems to work for CDI 2.0 (https://stackoverflow.com/a/54107969/3375325). – jansohn Jan 09 '19 at 10:41
0

I solved this problem. I am using Jetty 9.4.14, Jersey 2.28 and Weld (servlet-shaded) 3.1.0. This is the list of dependencies for Java 11.

//Jersey:
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.1.jar
jaxb-impl-2.3.0.1.jar
javax.ws.rs-api-2.1.1.jar
javax.activation-1.2.0.jar
jersey-container-jetty-http-2.28.jar
jersey-container-servlet-core-2.28.jar
jersey-server-2.28.jar
jersey-common-2.28.jar
jersey-client-2.28.jar
//Jersey + CDI:
jersey-bean-validation-2.28.jar
bean-validator-2.5.0-b06.jar
jersey-cdi1x-2.28.jar
jersey-cdi1x-servlet-2.28.jar
jersey-hk2-2.28.jar
hk2-api-2.5.0.jar
hk2-utils-2.5.0.jar
hk2-locator-2.5.0.jar

More information you can find in this Jersey issue.

Pavel_K
  • 8,216
  • 6
  • 44
  • 127