Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotation to prevent jackson to use JAXB annotations! #11

Closed
SamSoldatenko opened this issue Oct 8, 2016 · 7 comments
Closed

Annotation to prevent jackson to use JAXB annotations! #11

SamSoldatenko opened this issue Oct 8, 2016 · 7 comments

Comments

@SamSoldatenko
Copy link

Annotation to completely prevent jackson from using JAXB annotations!
see http://stackoverflow.com/questions/5005668/configure-jersey-jackson-to-not-use-xmlelement-field-annotation-for-json-field/5008595

@JacksonDontUseJaxbAnnotationsInThisClassItIsNotForYou()
@XmlRootElement
class X<T> {
    @XmlElementRefs({
       @XmlElementRef(name = "y", type = Y.class)
    })
    List<T> items;

    @XmlElement("xmlname")
    String jsonName;
}
class Y {
    String a;
    String b;
}

Should produce

{
    "items": [
        {
            "a": null,
            "b": null
        }
    ],
    "jsonName": null
}
@cowtowncoder
Copy link
Member

You are aware that it is possible to avoid use of JAXB annotations by not registering JAXBAnnotationsIntrospector? Granted this is sometimes done by a framework on your behalf so it may be hidden.

@SamSoldatenko
Copy link
Author

My initial offer was wrong. Sorry.
I want Jackson to IGNORE JaxB annotations by default. Completely! All of them! No exceptions!

Same time, I want jackson have special annotation to honor jaxb annotation (if somebody likes it).

@JacksonHonorJaxbAnnotations
@XmlRootElement
class X {
    @XmlElement(name = "description")
    String summary
}

As Java EE developer I control my components only, not container configurations. My customers want to deploy my components in any Java EE container. They expect, my components will produce valid XML and JSON data all the time, not only when they break down the JAXBAnnotationsIntrospector in their apps servers.

Now I have 2 ways

  1. Create custom Json producer
  2. Create second set of entities (without JaxB annotations) to use when I produce json.

Dear jackson developers! You have done GREAT job! You have Excellent set of Json annotations! Let me use it to configure JSON format on the same entity where I use Jaxb annotations to configure XML format. Please, please, please!!!!

@cowtowncoder
Copy link
Member

@SamSoldatenko Jackson does not support JAXB annotations by default. Optional support can be enabled using this module:

https://github.com/FasterXML/jackson-module-jaxb-annotations/

and specifically registering with:

 objectMapper.registerModule(new JaxbAnnotationModule());

Now: since you are having the issue, I suspect you are using Jackson via a framework that does enable JAXB annotation support by default. If so, it would be good to figure out a way to either prevent registration. If this is not feasible, it should still be possible to reset annotation introspection settings with

 objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());

(or just create new, plain ObjectMapper -- this is the default set up).

I hope this helps.

@SamSoldatenko
Copy link
Author

Wow!!! Thank you, very much!
Looks like its wildfly's fault!
https://github.com/wildfly/wildfly/blob/master/feature-pack/src/main/resources/modules/system/layers/base/com/fasterxml/jackson/jaxrs/jackson-jaxrs-json-provider/main/module.xml#L28
They include jackson-module-jaxb-annotations in default configuration!

@SamSoldatenko
Copy link
Author

I deleted jackson-module-jaxb-annotations from wildfly configuration. And now first call to my API generates HTTP 500!

20:17:59,721 ERROR [io.undertow.request] (default task-3) UT005023: Exception handling request to /api/companies: java.lang.NoClassDefFoundError: com/fasterxml/jackson/module/jaxb/JaxbAnnotationIntrospector
    at com.fasterxml.jackson.jaxrs.json.JsonMapperConfigurator._resolveIntrospector(JsonMapperConfigurator.java:109)
    at com.fasterxml.jackson.jaxrs.json.JsonMapperConfigurator._resolveIntrospectors(JsonMapperConfigurator.java:84)
    at com.fasterxml.jackson.jaxrs.cfg.MapperConfiguratorBase._setAnnotations(MapperConfiguratorBase.java:120)
    at com.fasterxml.jackson.jaxrs.json.JsonMapperConfigurator.getDefaultMapper(JsonMapperConfigurator.java:45)
    at com.fasterxml.jackson.jaxrs.base.ProviderBase.locateMapper(ProviderBase.java:867)
    at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:145)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:131)
    at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:60)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:120)
    at org.jboss.resteasy.security.doseta.DigitalSigningInterceptor.aroundWriteTo(DigitalSigningInterceptor.java:145)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124)
    at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.aroundWriteTo(GZIPEncodingInterceptor.java:89)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124)
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:98)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:473)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:422)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:209)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:221)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector from [Module "com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider:main" from local module loader @1da51a35 (finder: local module finder @16022d9d (roots: /opt/jboss/wildfly/modules,/opt/jboss/wildfly/modules/system/layers/base))]
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
    at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
    ... 58 more

Second and subsequent calls works well.

Lets GO back to point!

  1. Object <-> JSON transformation MUST be in components developers hands.
  2. Object <-> XML transformation MUST be in components developer hands.
  3. XML != JSON.

Can you please deprecate JaxbAnnotationIntrospector and never use JaxB annotations to format JSON?

@SamSoldatenko
Copy link
Author

SamSoldatenko commented Oct 10, 2016

Temporary workaround:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector
import groovy.transform.CompileStatic

import javax.ws.rs.Produces
import javax.ws.rs.core.MediaType
import javax.ws.rs.ext.ContextResolver
import javax.ws.rs.ext.Provider

@CompileStatic
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonContextResolver implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper;

    public JacksonContextResolver() throws Exception {
        this.objectMapper = new ObjectMapper()
        this.objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector())
    }

    public ObjectMapper getContext(Class<?> objectType) {
        return objectMapper;
    }
}

This jackson libs is required to compile.

    providedCompile 'com.fasterxml.jackson.core:jackson-annotations:2.8.3'
    providedCompile 'com.fasterxml.jackson.core:jackson-databind:2.8.3'
    providedCompile 'com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.8.3'

@cowtowncoder
Copy link
Member

Can you please deprecate JaxbAnnotationIntrospector and never use JaxB annotations to format JSON?

No. I'm sorry but this makes no sense. It was added specifically because many others DO want to use JAXB annotations due to various reasons. If you do not want it, don't add it; if you are using a framework, work with their developers to get voice heard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants