eclipse-ee4j / jersey

Eclipse Jersey Project - Read our Wiki:
https://github.com/eclipse-ee4j/jersey/wiki
Other
690 stars 351 forks source link

Issue with JacksonFeature and osgi #4554

Open ebersb opened 4 years ago

ebersb commented 4 years ago

Hi,

I'm not sure if this is a bug or I configured something wrong ?

I use jersey in an osgi (karaf 4.2.9) environment with java 8.

I updated jersey from 2.30.1 to 2.31 and jackson from 2.11.0 to 2.11.2. After update we receive the following exception: org.glassfish.hk2.api.MultiException: A MultiException has 2 exceptions. They are:

  1. java.util.ServiceConfigurationError: com.fasterxml.jackson.databind.Module: Provider com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule not found
  2. java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.jackson.internal.DefaultJacksonJaxbJsonProvider

I think this depends on the feature PULL 4447

The setup looks like:

   public static final class Configuration extends ResourceConfig
    {
        public Configuration()
        {
            property(FEATURE_AUTO_DISCOVERY_DISABLE, true);
            property(METAINF_SERVICES_LOOKUP_DISABLE, true);

            register(ExceptionMapper.class);
            register(ObjectMapperProvider.class);
            register(JacksonFeature.class);

Thanks and Regards

jansupol commented 4 years ago

There seems to be some missing dependency, Jersey depends on

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>

but your settings seem to be complaining about

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
</dependency>

Does it work when you keep Jackson 2.11.0?

Dronko commented 3 years ago

I had the same problem. It turns out that version 2.31 needs a new resource file, META-INF/services/com.fasterxml.jackson.databind.Module supplied by jackson-module-jaxb-annotations/2.10.2

So switching classloader to one that can find the file before registering the servlet solved it for me:

        ClassLoader classLoader = JaxbAnnotationModule.class.getClassLoader();
        ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(classLoader);
        myHttpService.registerServlet(...);
        Thread.currentThread().setContextClassLoader(originalContextClassLoader);

Hope that helps.

ICTKevinWong commented 3 years ago

I am running into this exact same issue with Jersey Client (Was upgrading from Jersey 1.x to 2.34). Is there any more information on fixing this? I have tried working with Jackson 2.11.0 and no dice there.

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.34</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.34</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.inject</groupId>
        <artifactId>jersey-hk2</artifactId>
        <version>2.34</version>
    </dependency>
https://www.baeldung.com/jersey-jax-rs-client
        final WebTarget webResource = createWebTarget(url, nodeCredential);
        final Response response = webResource
                .request(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .delete();
        log.debug("Response=" + response.toString());
        return response;

`1. java.util.ServiceConfigurationError: com.fasterxml.jackson.databind.Module: Provider com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule not found

  1. java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.jackson.internal.DefaultJacksonJaxbJsonProvider

    org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368) org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:463) org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:59) org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:47) org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:74) java.util.concurrent.FutureTask.run(FutureTask.java:266) org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:131) org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:176) org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:98) org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2102) org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:93) org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:67) org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.lambda$getAllServiceHolders$0(AbstractHk2InjectionManager.java:136) java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.getAllServiceHolders(AbstractHk2InjectionManager.java:140) org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.getAllServiceHolders(ImmediateHk2InjectionManager.java:30) org.glassfish.jersey.internal.inject.Providers.getServiceHolders(Providers.java:307) org.glassfish.jersey.internal.inject.Providers.getCustomProviders(Providers.java:151) org.glassfish.jersey.message.internal.MessageBodyFactory.initialize(MessageBodyFactory.java:219) org.glassfish.jersey.client.ClientMessageBodyFactory$MessageBodyWorkersConfigurator.postInit(ClientMessageBodyFactory.java:75) org.glassfish.jersey.client.ClientConfig$State.lambda$initRuntime$2(ClientConfig.java:461) java.util.Arrays$ArrayList.forEach(Arrays.java:3880) org.glassfish.jersey.client.ClientConfig$State.initRuntime(ClientConfig.java:461) org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:317) org.glassfish.jersey.client.ClientConfig.getRuntime(ClientConfig.java:819) org.glassfish.jersey.client.ClientRequest.getClientRuntime(ClientRequest.java:176) org.glassfish.jersey.client.ClientRequest.getInjectionManager(ClientRequest.java:567) org.glassfish.jersey.client.JerseyWebTarget.onBuilder(JerseyWebTarget.java:371) org.glassfish.jersey.client.JerseyWebTarget.request(JerseyWebTarget.java:206) org.glassfish.jersey.client.JerseyWebTarget.request(JerseyWebTarget.java:38)

    .doGetApiCall(ApiMnodeHelper.java:68)`
senivam commented 3 years ago

@ICTKevinWong do you run this in osgi environement? In which if so?

basically there should be a dependency for

        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jaxb-annotations</artifactId>
        </dependency>

but if you are running this in an OSGi env, there could be missing bundle like:

mavenBundle().groupId("com.fasterxml.jackson.module").artifactId("jackson-module-jaxb-annotations")
                        .versionAsInProject()
ICTKevinWong commented 3 years ago

I am running this as a vCenter plugin which I believe is a Virgo Server

Bundle Structure of the failure

plugin-package.xml
│
└───plugins
    │   com.springsource.javax.validation-1.0.0.GA.jar
    │   com.springsource.org.objectweb.asm-1.5.3.jar
    │   com.springsource.org.objectweb.asm.attrs-1.5.3.jar
    │   hsqldb-2.5.2.jar
    │   <COMPANY DATASERVICES>
    │
    └───<COMPANY DATASERVICES>
        │   antlr-2.7.7.jar
        │   aopalliance-repackaged-2.6.1.jar
        │   application.properties
        │   base64-2.3.9.jar
        │   byte-buddy-1.0.2.jar
        │   classmate-1.3.0.jar
        │   commons-codec-1.15.jar
        │   commons-lang3-3.12.0.jar
        │   commons-logging-1.2.jar
        │   dom4j-1.6.1.jar
        │   dom4j-2.1.1.jar
        │   gson-2.6.2.jar
        │   hibernate-commons-annotations-5.0.1.Final.jar
        │   hibernate-core-5.2.18.Final.jar
        │   hibernate-entitymanager-5.2.18.Final.jar
        │   hibernate-jpa-2.1-api-1.0.0.Final.jar
        │   hk2-api-2.6.1.jar
        │   hk2-locator-2.6.1.jar
        │   hk2-utils-2.6.1.jar
        │   httpclient-4.5.13.jar
        │   httpcore-4.4.13.jar
        │   jackson-annotations-2.12.2.jar
        │   jackson-core-2.12.2.jar
        │   jackson-databind-2.12.2.jar
        │   jackson-module-jaxb-annotations-2.12.2.jar
        │   jakarta.activation-api-1.2.1.jar
        │   jakarta.annotation-api-1.3.5.jar
        │   jakarta.inject-2.6.1.jar
        │   jakarta.ws.rs-api-2.1.6.jar
        │   jakarta.xml.bind-api-2.3.2.jar
        │   jandex-2.0.3.Final.jar
        │   javassist-3.21.0-GA.jar
        │   jboss-logging-3.3.1.Final.jar
        │   jboss-transaction-api_1.2_spec-1.0.1.Final.jar
        │   jersey-client-2.34.jar
        │   jersey-common-2.34.jar
        │   jersey-entity-filtering-2.34.jar
        │   jersey-hk2-2.34.jar
        │   jersey-media-json-jackson-2.34.jar
        │   joda-time-2.10.10.jar
        │   jsch-0.1.55.jar
        │   log4j-1.2.17.jar
        │   log4j.properties
        │   org.dom4j.dom4j-1.6.1.jar
        │   osgi-resource-locator-1.0.3.jar
        │   slf4j-api-1.7.30.jar
        │   slf4j-log4j12-1.7.30.jar
        │   yavijava-6.0.05.jar
        │
        ├───com
        │   └───<MY COMPANY FILES>
        │
        └───META-INF
            │   MANIFEST.MF
            │   persistence.xml
            │   SELFSIGN.RSA
            │   SELFSIGN.SF
            │
            ├───maven
            │   └───<COMPANY PATH>
            │       └───<DATASERVICES>
            │               pom.properties
            │               pom.xml
            │
            └───spring
                    bundle-context-osgi.xml
                    bundle-context.xml

Embedded-Artifacts Snippet in Manifest

,jersey-common-2.34.jar;g="org.glassfish.jersey.core";
 a="jersey-common";v="2.34",jakarta.annotation-api-1.3.5.jar;g="jakart
 a.annotation";a="jakarta.annotation-api";v="1.3.5",osgi-resource-loca
 tor-1.0.3.jar;g="org.glassfish.hk2";a="osgi-resource-locator";v="1.0.
 3",jakarta.inject-2.6.1.jar;g="org.glassfish.hk2.external";a="jakarta
 .inject";v="2.6.1",jersey-media-json-jackson-2.34.jar;g="org.glassfis
 h.jersey.media";a="jersey-media-json-jackson";v="2.34",jersey-entity-
 filtering-2.34.jar;g="org.glassfish.jersey.ext";a="jersey-entity-filt
 ering";v="2.34",jackson-annotations-2.12.2.jar;g="com.fasterxml.jacks
 on.core";a="jackson-annotations";v="2.12.2",jackson-databind-2.12.2.j
 ar;g="com.fasterxml.jackson.core";a="jackson-databind";v="2.12.2",jac
 kson-core-2.12.2.jar;g="com.fasterxml.jackson.core";a="jackson-core";
 v="2.12.2",jackson-module-jaxb-annotations-2.12.2.jar;g="com.fasterxm
 l.jackson.module";a="jackson-module-jaxb-annotations";v="2.12.2",jakarta
senivam commented 3 years ago

@ICTKevinWong thanks for reporting those dependencies. So, for proper OSGi initialization of jackson-module-jaxb-annotations-[version].jar it's required to have following chain of JARs:

jackson-annotations-[version].jar
jackson-core-[version].jar
jackson-databind-[version].jar
jackson-module-jaxb-annotations-[version].jar
jaxb-api-[jaxb-api-version].jar 

from the dependencies list I see you have all jackson-* related dependencies, but I'm not able to find jaxb-api dependency there. Please check if jaxb-api is included as well.

ICTKevinWong commented 3 years ago

No dice.

I might be mistaken, but I believe that jakarta.xml.bind-api-2.3.2.jar is the Eclipse Jaxb-api and should satisfy the requirements.

I think there are some issues that I need to work out with VMware as this bundle works with the latest vCenter version and not previous versions. For the time being I will use Jersey 2.34 and tag jersey-media-json-jackson to 2.30.1. It's likely some sort of dependency collision with the app server

For future reference, I understand that I sort of hijacked this issue; would it have been better to create a new issue and reference this thread?

senivam commented 3 years ago

For the time being I will use Jersey 2.34 and tag jersey-media-json-jackson to 2.30.1.

you mean for that combination it works for you?

I believe that jakarta.xml.bind-api-2.3.2.jar is the Eclipse Jaxb-api and should satisfy the requirements

yes, my bad, I've missed that. It perfectly works for jackson-module-jaxb-annotations.

regarding new issue - I think we can keep going here, since we've already discussed a lot and the issue is relevant - you are running the code in osgi environment.

ICTKevinWong commented 3 years ago

you mean for that combination it works for you?

Yes, mixing versions seems to work fine with jersey client.

A little bit more information that may be helpful. I've been playing with mixing versions and the following POM and Jar bundle functionally works. We can use the 2.34 and Jackson 2.12.3 as long as Jersey-media-json-jackson is 2.30.1

... jackson-annotations-2.12.3.jar | jackson-core-2.12.3.jar | jackson-databind-2.12.3.jar | jackson-module-jaxb-annotations-2.12.3.jar | jakarta.activation-api-1.2.1.jar | jakarta.annotation-api-1.3.5.jar | jakarta.inject-2.6.1.jar | jakarta.ws.rs-api-2.1.6.jar | jakarta.xml.bind-api-2.3.2.jar | jandex-2.0.3.Final.jar | javassist-3.21.0-GA.jar | jboss-logging-3.3.1.Final.jar | jboss-transaction-api_1.2_spec-1.0.1.Final.jar | jersey-client-2.34.jar | jersey-common-2.34.jar | jersey-entity-filtering-2.34.jar | jersey-hk2-2.34.jar | jersey-media-json-jackson-2.30.1.jar | joda-time-2.10.10.jar | jsch-0.1.55.jar | log4j-1.2.17.jar | log4j.properties | org.dom4j.dom4j-1.6.1.jar | osgi-resource-locator-1.0.3.jar ...

<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>2.30.1</version>
        <exclusions>
            <exclusion>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.fasterxml.jackson.module</groupId>
                <artifactId>jackson-module-jaxb-annotations</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.glassfish.jersey.core</groupId>
                <artifactId>jersey-common</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.glassfish.jersey.ext</groupId>
                <artifactId>jersey-entity-filtering</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-common</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-entity-filtering</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.inject</groupId>
        <artifactId>jersey-hk2</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-jaxb-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>
JensGabe commented 2 years ago

A proper Jakarta edition of JacksonFeature which uses the Jackson module "jackson-jakarta-rs-json-provider" instead of "jackson-module-jaxb-annotations" should be implemented. "jackson-module-jaxb-annotations" module internally uses javax.xml.bind. Whereas the "jackson-jakarta-rs-json-provider" module uses jakarta.xml.bind. Available from Jackson v2.13

jansupol commented 2 years ago

@JensGabe your comment probably does not relate to this OSGi issue. Latest Jersey 3.x already implements the dependency on jackson-module-jakarta-xmlbind-annotations, but it is still possible to use jackson-module-jaxb-annotations/javax.xml.bind.*, too.

JensGabe commented 2 years ago

Found #4891 which regards Jackson 2.13, but the implementation seems a bit odd, as the code now contains references to both mentioned jackson modules? An approach as in Jackson with separate module for each to avoid having hardcoded references to both versions would perhaps be simpler to use.

jansupol commented 2 years ago

Found https://github.com/eclipse-ee4j/jersey/issues/4891 which regards Jackson 2.13, but the implementation seems a bit odd, as the code now contains references to both mentioned jackson modules?

The reference to the javax modules is optional. It is there for backward compatibility, should someone use the module with both JAX-B/2 (javax) and JAX-B/3 (jakarta). Using two modules is an option, but it leads to code duplication and many modules for Jackson. I believe Jackson will come with the support of JAX-B/4 (EE10), which would have been another module.

JensGabe commented 2 years ago

Ahh, I do not need the jackson-module-jaxb-annotations anymore, only the jackson-module-jakarta-xmlbind-annotations - thanks