Giter Site home page Giter Site logo

fasterxml / jackson-modules-base Goto Github PK

View Code? Open in Web Editor NEW
166.0 16.0 77.0 4.31 MB

Uber-project for foundational modules of Jackson that build directly on core components but nothing else; not including data format or datatype modules

License: Apache License 2.0

Java 99.12% Shell 0.01% Logos 0.87%

jackson-modules-base's Introduction

Overview

This is a multi-module umbrella project for Jackson modules that are considered foundational, building on core databind, but not including datatype or data format modules, or JAX-/Jakarta-RS providers. Not all "general" modules are included here; this grouping is to be used for more mature (and generally slower moving, stable) modules.

Currently included are:

Status

Build Status

License

All modules are licensed under Apache License 2.0.

Additionally, 2.x versions of Afterburner and Mr Bean use ASM, licensed as per:

https://asm.ow2.io/license.html

whereas 3.0 will use ByteBuddy (licensed as per https://github.com/raphw/byte-buddy/blob/master/LICENSE)

Using Jakarta

Jackson 2.13 and later

With 2.13, you need to choose either:

  • jackson-module-jaxb-annotations for "old JAXB" (2.x): supports javax.xml.bind annotations
  • jackson-module-jakarta-xmlbind-annotations for "new Jakarta JAXB" (3.x): supports jakarta.xml.bind annotations

(in theory you can even use both, with databind AnnotationIntrospectorPair, but more often you will only want one of these)

Note that Jakarta version was added in Jackson 2.13 and was not available for earlier versions.

Jackson 2.12 (only)

Alternatively if using Jackson 2.12, there is a specific variant of jackson-module-jaxb-annotations available, usable with Maven classifier of "jakarta". You can use it instead of "old" JAXB variant by specifying classifier like so:

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

More

See Wiki for more information (javadocs).

jackson-modules-base's People

Contributors

bsanchezb avatar carterkozak avatar cowtowncoder avatar dansanduleac avatar dependabot[bot] avatar eranl avatar frsyuki avatar gedmarc avatar hellooo7 avatar hildoye avatar jamezp avatar jbagdis avatar jdunnin avatar joohyukkim avatar josephlbarnett avatar linlinnn avatar pjfanning avatar qnzvna avatar rayzhang001 avatar robbytx avatar stevenschlansker avatar stevestorey avatar tacoo avatar yeikel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jackson-modules-base's Issues

Guice Interceptors (AOP) are not activated when attached to ObjectMapper based instances

(note: moved from https://github.com/FasterXML/jackson-module-guice/issues/4)

In a Guice Injector, I tried to chain the Jackson Module Guice's ObjectMapperModule with a regular Guice Module having regular bindings (using: binder.bind()). Instance retrieval from the Guice Injector works very well, both directly from the Guice Injector and indirectly through Jackson Module Guice's ObjectMapper.

Additionally, I tried to add a new Guice Module to the chain of Guice Modules with inside a custom Guice Interceptor (using: binder.bindInterceptor).

Instances retrieved directly from the Guice Injector show that they are instantiated from classes like: $$EnhancerByGuice$$25c21b02. These instances work with the Guice Interceptor as expected; method calls get redirected the Interceptor when the annotated methods get invoked.

However, instances retrieved indirectly from the Guice Injector through the ObjectMapper first show that they are instantiated from the original class names like: (no enhancements). Additionally, no interception (redirection) is executed on these instances when annotated methods are invoked.

Am I missing something here?

Implement `hashCode()`

It would also make sense to implement hashCode() unless target class already defines it. As with equality, hash code should be calculated using backing fields added.

Afterburner with joda module does not always include null values

Afterburner together with joda module does not always include null values.

Test to reproduce:

    @JsonInclude(JsonInclude.Include.ALWAYS)
    static class TestClass {
        @JsonProperty("name")
        private String name;
        @JsonProperty("id")
        private String id;
        @JsonProperty("created_at")
        private DateTime created_at;
        @JsonProperty("updated_at")
        private DateTime updated_at;

        public String getName() {
            return name;
        }

        public TestClass setName(String name) {
            this.name = name;
            return this;
        }

        public String getId() {
            return id;
        }

        public TestClass setId(String id) {
            this.id = id;
            return this;
        }

        public DateTime getCreated_at() {
            return created_at;
        }

        public DateTime getUpdated_at() {
            return updated_at;
        }

        public TestClass setCreated_at(final DateTime created_at) {
            this.created_at = created_at;
            return this;
        }

        public TestClass setUpdated_at(final DateTime updated_at) {
            this.updated_at = updated_at;
            return this;
        }

    }

    @Test
    public void test_serialize_jackson() throws JsonProcessingException {

        TestClass tilstand = new TestClass()
                .setId(null)
                .setName("name")
                .setUpdated_at(null)
                .setCreated_at(new DateTime());

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JodaModule());
        mapper.registerModule(new AfterburnerModule());

        String json = mapper.writeValueAsString(tilstand);

        assertThat(json, containsString("id"));
        assertThat(json, containsString("name"));
        assertThat(json, containsString("updated_at"));
        assertThat(json, containsString("created_at"));
    }

If you comment out AfterburnerModule, the test passes. I am using v. 2.6.3

Also tried against current master here with datatype-joda 2.7.4, and the test fails. I could publish it, but I had to mess around with some of the maven poms to get it running.

[mrbean] Failed to load class com.fasterxml.jackson.module.mrbean.generated...

I'm using the Play! framework in Java with an interface like

public interface AbstractMsg {
    public String getValue();
}

And registered mapper modules at startup

ObjectMapper mapper = play.libs.Json.mapper();
mapper.registerModule(new ParameterNamesModule());
mapper.registerModule(new MrBeanModule());
play.libs.Json.setObjectMapper(mapper);

And when trying to "materialize" the interface with JSON content

{ "value" : "did it work?" }

I get a nice Exception

akka.actor.OneForOneStrategy - com.fasterxml.jackson.databind.JsonMappingException: Failed to load class 'com.fasterxml.jackson.module.mrbean.generated.models.mensajes.AbstractMsg': models/mensajes/AbstractMsg
java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Failed to load class 'com.fasterxml.jackson.module.mrbean.generated.models.mensajes.AbstractMsg': models/mensajes/AbstractMsg
...
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Failed to load class 'com.fasterxml.jackson.module.mrbean.generated.models.mensajes.AbstractMsg': models/mensajes/AbstractMsg

I have to mention that the "materialization" on the interface is happening inside an Actor, which can run in a different thread from which the ObjectMapper and this module was instantiated.

I have tried different combinations and could not find the cause, but I suspect the class loader of the framework is not available to Jackson, but I'm only speculating.

Java: 1.8
Play: 2.4, 2.5
Module version 2.6.0, 2.6.1, 2.7.1

XML: Different class configurations required for marhalling/unmarshalling of collections

See this test class:

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import org.junit.Before;
import org.junit.Test;

import java.beans.ConstructorProperties;
import java.io.IOException;
import java.util.Collection;

public class CollectionMarshalling {

    private static final String XML = "<root><names><name>name1</name><name>name2</name></names></root>";

    private XmlMapper xmlMapper;

    @Before
    public void setUp() {
        xmlMapper = new XmlMapper(new JacksonXmlModule());
    }

    @Test
    public void testMarshallingWithoutWrapper() throws JsonProcessingException {
        assertEquals(
            "<root><names><name>name1</name><name>name2</name></names></root>",
            xmlMapper.writeValueAsString(new RootWithoutWrapper(asList("name1", "name2")))
        );
    }

    @Test
    public void testMarshallingWithWrapper() throws JsonProcessingException {
        assertEquals(
            XML,
            xmlMapper.writeValueAsString(new RootWithWrapper(asList("name1", "name2")))
        );
    }

    @Test
    public void testUnmarshallingWithoutWrapper() throws IOException {
        assertEquals(
            asList("name1", "name2"),
            xmlMapper.readValue(XML, RootWithoutWrapper.class).names
        );
    }

    @Test
    public void testUnmarshallingWithWrapper() throws IOException {
        assertEquals(
            asList("name1", "name2"),
            xmlMapper.readValue(XML, RootWithWrapper.class).names
        );
    }

    @JacksonXmlRootElement(localName = "root")
    public static class RootWithoutWrapper {
        @JacksonXmlProperty
        Collection<String> names;

        @ConstructorProperties({"names"})
        public RootWithoutWrapper(Collection<String> names) {
            this.names = names;
        }
    }

    @JacksonXmlRootElement(localName = "root")
    public static class RootWithWrapper {
        @JacksonXmlElementWrapper(localName = "names")
        @JacksonXmlProperty(localName = "name")
        Collection<String> names;

        @ConstructorProperties({"names"})
        public RootWithWrapper(Collection<String> names) {
            this.names = names;
        }
    }

}

This is the test result:

  • testMarshallingWithoutWrapper: FAILED
  • testMarshallingWithWrapper: SUCCESS
  • testUnmarshallingWithWrapper: ERROR
  • testUnmarshallingWithoutWrapper: SUCCESS

You see, if I want to unmarshall XML I must not use @JacksonXmlElementWrapper. If I want to marshall I have to use @JacksonXmlElementWrapper. This impossible with one class.

`IncompatibleClassChangeError` deserializing interface methods with default impl

With Afterburner I'm getting the exception java.lang.IncompatibleClassChangeError: Found class <MyClass>, but interface was expected trying to deserialize an object where a setter is implemented in an interface.

I've tested with Jackson+Afterburner 2.8.7, 2.8.10 and 2.9.0 and all fail in the same way. (jdk 8)

java.lang.IncompatibleClassChangeError: Found class com.fasterxml.jackson.module.afterburner.deser.TestInterfaceDeser$Model, but interface was expected

	at com.fasterxml.jackson.module.afterburner.deser.TestInterfaceDeser$Model$Access4JacksonDeserializer5b28f286.stringSetter(com/fasterxml/jackson/module/afterburner/deser/TestInterfaceDeser$Model$Access4JacksonDeserializer.java)
	at com.fasterxml.jackson.module.afterburner.deser.SettableStringMethodProperty.deserializeAndSet(SettableStringMethodProperty.java:53)
	at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:159)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
	at com.fasterxml.jackson.module.afterburner.deser.testInterfaceDeserialize(TestInterfaceDeser.java:40)

Here's a test case that reproduces the issue:

package com.fasterxml.jackson.module.afterburner.deser;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class TestInterfaceDeser {

    public interface Typed {
        String getType();
        default void setType(String type) {
            if (!getType().equals(type)) {
                throw new IllegalStateException(String.format("Expected '%s': %s", getType(), type));
            }
        }
    }

    public static class Model implements Typed {
        @Override
        public String getType() {
            return "Model";
        }
    }

    @Test
    public void testInterfaceDeserialize() throws Exception {
        Model model = new Model();

        ObjectMapper mapper = new ObjectMapper().registerModule(new AfterburnerModule());

        String json = mapper.writeValueAsString(model);
        assertEquals("{\"type\":\"Model\"}", json);

        // Throws: java.lang.IncompatibleClassChangeError: Found class com.fasterxml.jackson.module.afterburner.deser. TestInterfaceDeser$Model, but interface was expected
        Model roundTrip = mapper.readValue(json, Model.class);

        assertNotNull(roundTrip);
    }
}

AbstractTypeMaterializer attempts to materialize Iterable

AbstractTypeMaterializer should skip Iterable.class.

Something like this perhaps?

        //current
        if (type.isContainerType() || type.isPrimitive() || type.isEnumType() || type.isThrowable() ||
                type.getRawClass() == Number.class)
        {
            return null;
        }
       Class<?> cls = type.getRawClass();

        //fix
        Class<?> cls = type.getRawClass();
        if (type.isContainerType() || type.isPrimitive() || type.isEnumType() || type.isThrowable() ||
                cls  == Number.class || cls == Iterable.class)
        {
            return null;
        }       

Serialization with Afterburner causes Java VerifyError for generic with String as type

java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

Jackson version: 2.7.0 (jackson-core, jackson-databind, jackson-annotations)
Afterburner version: 2.7.0

Please take following example and run it through an ObjectMapper with afterburner module registered.

public static abstract class AbstractMyClass<ID> {

    private ID id;

    AbstractMyClass(ID id) {
        setId(id);
    }

    public ID getId() {
        return id;
    }

    public void setId(ID id) {
        this.id = id;
    }
}

public static class MyClass extends AbstractMyClass<String> {
    public MyClass(String id) {
        super(id);
    }
}

Try to serialize MyClass and you will get the following error:

java.lang.VerifyError: Bad return type
Exception Details:
Location:
UnitTest$MyClass$Access4JacksonDeserializer26caf25d.stringGetter(Ljava/lang/Object;I)Ljava/lang/String; @10: areturn
Reason:
Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'java/lang/String' (from method signature)
Current Frame:
bci: @10
flags: { }
locals: { 'MyClass$Access4JacksonDeserializer26caf25d', 'java/lang/Object', integer, 'UnitTest$MyClass' }
stack: { integer, 'java/lang/Object' }
Bytecode:
0x0000000: 2bc0 000d 4e1c 2db6 0011 b0bb 0013 59bb
0x0000010: 0015 5912 17b7 001a 1cb6 001e b600 22b7
0x0000020: 0023 bf

at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.newInstance(Class.java:412)
at com.fasterxml.jackson.module.afterburner.ser.PropertyAccessorCollector.findAccessor(PropertyAccessorCollector.java:99)
at com.fasterxml.jackson.module.afterburner.ser.SerializerModifier.changeProperties(SerializerModifier.java:63)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:401)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:271)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:223)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:157)
at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1215)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1167)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:490)
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:688)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:107)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1428)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1129)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1001)

Bad performance with AfterburnerModule setUseValueClassLoader(false)

After reading through the Java 9 warning for afterburner issue, we added setUseValueClassLoader(false). The warnings disappeared, but the execution time for our integration tests increased by a factor 2 (when executed through gradle) to 10 (when executed through IntelliJ).

That is, when the objectmapper is configured like this
mapper.registerModule(new AfterburnerModule().setUseValueClassLoader(false));
the test execution time is 2x - 10x longer than when the objectmapper is configured like this
mapper.registerModule(new AfterburnerModule());
while everything else remains identical.

The affected integrations tests are executed using JUnit 4, and @RunWith either SpringJunit4ClassRunner or VertxUnitRunner.

Consider changing checks for `is std (de)serializer` for `BeanPropertyWriter`

Currently any deserializer/serializer that is not considered Jackson "standard" (de)serializer will lead to de-optimizing access. However, it should really only be necessary to do this for cases where handling would markedly differ:

  • String (the original reported problem, issue 59 (in old repo))
  • int/Integer
  • long/Long
  • boolean/Boolean

whereas other Object types seem unlikely to have problems due to optimized access.

The reason for being more selective is because there is some cost from de-optimizing; namely additional method call due to chaining, as well as loss of optimization itself.

JaxbAnnotationModule Serializes Object as Ref only Instead of as Full Object In some Cases

When using Jackson with JaxbAnnotationModule , if objects with similar ids appears in two different fields of an outer object , it is sometimes incorrectly serialized as a ref only, instead of as a full object
Case 1:
The Inner object class has both @xmlid and @xmlelement properties
One of the inner objects appear in a list field of the outer object, and another in another field
Unit Test to show problem:

class HasID
{
	String id;
	String name;
    @XmlID 
    @XmlElement
    public String getId() {
        return id;
    }
    @XmlElement
    public String getName() { return name; }
}

@XmlRootElement
class HasIDList
{
	List<HasID> elements = null;
    @XmlElement
    public List<HasID> getElements( ) { return elements; }
    public void setElements( List<HasID> elements ) { this.elements = elements; }
    HasID parent;
    @XmlElement 
    public HasID getParent() { return parent; }
}


public class SerializeAsFullObjectTest{

	@Test
	public void test() throws Exception {
		ObjectMapper mapper = new ObjectMapper();
		JaxbAnnotationModule jaxbAnnotationModule = new JaxbAnnotationModule();
		mapper.registerModule(jaxbAnnotationModule);

		HasID hasID = new HasID();   
		hasID.id = "1"; hasID.name="name1";
		HasID hasID2 = new HasID();
		hasID2.id = "1"; hasID2.name="name1";
		
		HasIDList idList = new HasIDList();
		idList.setElements(Arrays.asList(hasID,hasID2));
		idList.parent = hasID2;
		
		Assert.assertEquals("{\"elements\":[{\"id\":\"1\",\"name\":\"name1\"},{\"id\":\"1\",\"name\":\"name1\"}],\"parent\":{\"id\":\"1\",\"name\":\"name1\"}}", mapper.writeValueAsString(idList));
	}
}
 

The problem only appears when

  1. Using JaxbAnnotations, with @xmlid and ( @xmlelement or @XmlAttribute)
    and
    2A) The two inner objects have the same id, and appear in two different fields of the outer object, where one of them is a list
    -OR-
    2B) The same inner object is set as two different fields of the outer class

Unit Test for the second problem:

class HasID
{
	String id;
	String name;
    @XmlID 
    @XmlElement
    public String getId() {
        return id;
    }
    @XmlElement
    public String getName() { return name; }
}

@XmlRootElement
class OuterElement
{
    HasID parent;
    @XmlElement 
    public HasID getParent() { return parent; }
    HasID second;
    @XmlElement 
    public HasID getSecond() { return second; }

}

public class SameObjectSerializedFullTest {

	@Test
	public void test() throws Exception {
		ObjectMapper mapper = new ObjectMapper();
		JaxbAnnotationModule jaxbAnnotationModule = new JaxbAnnotationModule();
		mapper.registerModule(jaxbAnnotationModule);
		HasID hasID = new HasID();   
		hasID.id = "1"; hasID.name="name1";
		HasID hasID2 = new HasID();
		hasID2.id = "1"; hasID2.name="name1";
		OuterElement outerElement = new OuterElement();
		outerElement.parent = hasID;
		outerElement.second = hasID;
		Assert.assertEquals("{\"parent\":{\"id\":\"1\",\"name\":\"name1\"},\"second\":{\"id\":\"1\",\"name\":\"name1\"}}", mapper.writeValueAsString(outerElement));
	}
This is a real ( non academic ) problem in a current production project.

Afterburner issue with Karaf OSGI Container

I am trying to use AfterBurner in a OSGI Container.

In the same code base in one place it is working perfectly fine and in one place it is failing. The code where it is working looks like something like below (and is called first in the flow)

public static WFRequest fromJSON(String json, String targetClassName)
        throws ClassNotFoundException, IOException {
    WFRequest reqParam = null;
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new AfterburnerModule());
    reqParam = (WFRequest) mapper.readValue(json, Class.forName(targetClassName));
    return reqParam;
    }

The code where it is failing looks like below:-

@SuppressWarnings("unchecked")
    private static <T extends BaseCamelHTTPComponentResponse> T fromJSON(final JSONObject jsonObj,
        String serviceResponseClass) throws ClassNotFoundException, IOException {
    LOG.info("Response: {}, Marshalling it to an object of {}", jsonObj.toString(), serviceResponseClass);
    ObjectMapper objectMapper = new ObjectMapper();
    AfterburnerModule afterBurner = new AfterburnerModule();
    afterBurner.setUseOptimizedBeanDeserializer(false);
    objectMapper.registerModule(afterBurner);
    return (T) objectMapper.readValue(jsonObj.toString(), Class.forName(serviceResponseClass));
    }

In the second case it is failing with the following error:-

OrderException-GetOrdersHTTPFailure
com.fasterxml.jackson.databind.JsonMappingException: Failed to load class 'org.apache.camel.Message$Access4JacksonDeserializer98898f0f': com.fasterxml.jackson.module.afterburner.deser.BeanPropertyMutator
 at [Source: {"data":{"total":2,"order":[], "status":{"success":true}},"_metaData":{"urlParams":{}},"status":{"success":true,"errors":null,"httpStatusCode":200}}; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:290)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:269)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:444)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:948)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:446)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:296)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3908)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3803)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2797)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.jabong.orchestratorservice.basecomponent.http.JSONCamelHttpResponseHandler.marshallJSON(JSONCamelHttpResponseHandler.java:73)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.http.JSONCamelHttpResponseHandler.handleResponse(JSONCamelHttpResponseHandler.java:38)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.http.BaseCamelHTTPComponent.prepareResponse(BaseCamelHTTPComponent.java:133)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.http.BaseCamelHTTPComponent.call(BaseCamelHTTPComponent.java:88)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.node.HttpWFNode.executeRequest(HttpWFNode.java:130)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.node.HttpWFNode.executeWithRetry(HttpWFNode.java:118)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.node.HttpWFNode.executeWithRetry(HttpWFNode.java:49)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.node.HttpWFNode.execute(HttpWFNode.java:43)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.adapter.order.executor.GetOrdersWorkflowExecutor.execute(GetOrdersWorkflowExecutor.java:44)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.adapter.order.OrderHelper.getMarketplaceOrders(OrderHelper.java:53)[286:basecomponent:0.0.1]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_77]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_77]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_77]
    at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_77]
    at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:408)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:279)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:252)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:177)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:68)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.bean.BeanProducer.process(BeanProducer.java:38)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.DelayProcessorSupport.process(DelayProcessorSupport.java:160)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.UnitOfWorkProducer.process(UnitOfWorkProducer.java:68)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:412)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:380)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:270)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:380)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:238)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:128)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:132)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:149)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.DefaultProducerTemplate.requestBody(DefaultProducerTemplate.java:301)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.impl.DefaultProducerTemplate.requestBody(DefaultProducerTemplate.java:331)[136:org.apache.camel.camel-core:2.16.1]
    at com.jabong.orchestratorservice.basecomponent.processor.AbstractProcessor.makeRequest(AbstractProcessor.java:47)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.processor.JSONRPCProcessor.processRequest(JSONRPCProcessor.java:167)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.processor.JSONRPCProcessor.processRequestAndSendResponse(JSONRPCProcessor.java:132)[286:basecomponent:0.0.1]
    at com.jabong.orchestratorservice.basecomponent.processor.JSONRPCProcessor.process(JSONRPCProcessor.java:72)[286:basecomponent:0.0.1]
    at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[136:org.apache.camel.camel-core:2.16.1]
    at org.apache.camel.component.jetty.CamelContinuationServlet.service(CamelContinuationServlet.java:170)[250:org.apache.camel.camel-jetty-common:2.16.1]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)[45:org.apache.geronimo.specs.geronimo-servlet_3.0_spec:1.0.0]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.Server.handle(Server.java:370)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)[50:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
    at java.lang.Thread.run(Thread.java:745)[:1.8.0_77]
Caused by: java.lang.IllegalArgumentException: Failed to load class 'org.apache.camel.Message$Access4JacksonDeserializer98898f0f': com.fasterxml.jackson.module.afterburner.deser.BeanPropertyMutator
    at com.fasterxml.jackson.module.afterburner.util.MyClassLoader.loadAndResolve(MyClassLoader.java:100)
    at com.fasterxml.jackson.module.afterburner.deser.PropertyMutatorCollector.generateMutatorClass(PropertyMutatorCollector.java:204)[278:com.fasterxml.jackson.module.jackson-module-afterburner:2.7.4]
    at com.fasterxml.jackson.module.afterburner.deser.PropertyMutatorCollector.buildMutator(PropertyMutatorCollector.java:102)[278:com.fasterxml.jackson.module.jackson-module-afterburner:2.7.4]
    at com.fasterxml.jackson.module.afterburner.deser.DeserializerModifier.updateBuilder(DeserializerModifier.java:62)[278:com.fasterxml.jackson.module.jackson-module-afterburner:2.7.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:239)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:406)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)[267:com.fasterxml.jackson.core.jackson-databind:2.7.4]
    ... 86 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.module.afterburner.deser.BeanPropertyMutator
    at java.lang.ClassLoader.findClass(ClassLoader.java:530)[:1.8.0_77]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)[:1.8.0_77]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)[:1.8.0_77]
    at java.lang.ClassLoader.defineClass1(Native Method)[:1.8.0_77]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)[:1.8.0_77]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)[:1.8.0_77]
    at com.fasterxml.jackson.module.afterburner.util.MyClassLoader.loadAndResolve(MyClassLoader.java:94)
    ... 94 more

I have no issue in the MANIFEST.mf in the bundle. All the imports are added:-

Import-Package: com.fasterxml.jackson.core;resolut
 ion:=optional;version="[2.7,3)",com.fasterxml.jackson.databind;resoluti
 on:=optional;version="[2.7,3)",com.fasterxml.jackson.databind.annotatio
 n;resolution:=optional;version="[2.7,3)",com.fasterxml.jackson.module.a
 fterburner;resolution:=optional;version="[2.7,3)",org.json;reso
 lution:=optional,org.osgi.service.blueprint;version="[1.0.0,2.0.0)";res
 olution:=optional,com.fasterxml.jack
 son.databind.ser;version="[2.7,3)",com.fasterxml.jackson.databind.deser
 ;version="[2.7,3)",com.fasterxml.jackson.databind.ser.std;version="[2.7
 ,3)",com.fasterxml.jackson.databind.deser.std;version="[2.7,3)",com.fas
 terxml.jackson.module.afterburner.ser;version="[2.7,3)",com.fasterxml.j
 ackson.module.afterburner.deser;version="[2.7,3)"

...

Even doing bundle:headers in Karaf I am seeing all the bundles correctly imported

karaf@root>bundle:headers 286

basecomponent (286)
-------------------
Created-By = Apache Maven Bundle Plugin
Manifest-Version = 1.0
Bnd-LastModified = 1462969467812
Build-Jdk = 1.8.0_77
Built-By = debraj
Tool = Bnd-3.0.0.201509101326

Bundle-Blueprint = OSGI-INF/blueprint/authenticationBeans.xml,OSGI-INF/blueprint/awsBeans.xml,OSGI-INF/blueprint/blueprint.xml,OSGI-INF/blueprint/camelContext.xml,OSGI-INF/blueprint/catalogBeans.xml,OSGI-INF/blueprint/erpBeans.xml,OSGI-INF/blueprint/healthCheckBeans.xml,OSGI-INF/blueprint/orderBeans.xml,OSGI-INF/blueprint/productBeans.xml,OSGI-INF/blueprint/vendorBeans.xml
Bundle-ManifestVersion = 2
Bundle-SymbolicName = basecomponent
Bundle-Version = 0.0.1
Bundle-Name = basecomponent

Require-Capability = 
    osgi.ee;filter:=(&(osgi.ee=JavaSE)(version=1.8))


Import-Package = 
    com.fasterxml.jackson.annotation;resolution:=optional;version="[2.7,3)",
    com.fasterxml.jackson.core;resolution:=optional;version="[2.7,3)",
    com.fasterxml.jackson.databind;resolution:=optional;version="[2.7,3)",
    com.fasterxml.jackson.databind.annotation;resolution:=optional;version="[2.7,3)",
    com.fasterxml.jackson.module.afterburner;resolution:=optional;version="[2.7,3)",
    com.fasterxml.jackson.databind.ser;version="[2.7,3)",
    com.fasterxml.jackson.databind.deser;version="[2.7,3)",
    com.fasterxml.jackson.databind.ser.std;version="[2.7,3)",
    com.fasterxml.jackson.databind.deser.std;version="[2.7,3)",
    com.fasterxml.jackson.module.afterburner.ser;version="[2.7,3)",
    com.fasterxml.jackson.module.afterburner.deser;version="[2.7,3)"

...

Can you let me what could be going wrong? Just to add everything works perfectly fine if I run this as a normal jar outside Karaf OSGi container.

Can't put @JsonCreator on non-public ctor/method in signed jar

Hello,
I ran into this problem today.

(I am running 2.8.11 on all of my jackson libs, but as far as I see in the source, the problem still exists)

I have a signed jar, which contains a class whose protected constructor is annotated with @JsonCreator. During run time, I kept receiving the following:

java.lang.IllegalAccessError: tried to access method com.preempt.common.model.policy.FirewallTriggerDescriptor.()V from class com.preempt.common.model.policy.FirewallTriggerDescriptor$Creator4JacksonDeserializer1ddd0765

I found out the following: The FirewallTriggerDescriptor class, and the dynamic Deserializer class are loaded in different ClassLoaders, and therefore the protected constructor is not accessible. The reason this happens is due to loadAndResolve in MyClassLoader. When the Deserializer class code is generated, the code attempts to load it on the parent class loader:

Method method = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {String.class, byte[].class, int.class, int.class});
method.setAccessible(true);
return (Class<?>)method.invoke(getParent(), className.getDottedName(), byteCode, 0, byteCode.length);

This call to defineClass fails with a SecurityException, because the other classes in this package are signed, and this one isn't.

I can't see anyway around it. As it is, it means that Jackson can't be used with signed jars, unless all the @JsonCreator methods are defined as public.

Afterburner failing inside Karaf 3.0.5

I have a simple Hello World type Karaf Bundle. The activator code looks like below:-

public class HelloWorldActivator implements BundleActivator {
        @Override
        public void start(BundleContext bundleContext) throws Exception {
            System.out.println("STARTING DEMO: hello, world\n");
            System.out.println(getJsonDataAsString());
        }

        @Override
        public void stop(BundleContext bundleContext) throws Exception {
            System.out.println("STOPPING DEMO");
        }   

        private String getJsonDataAsString() {
            JsonDataBlob jsonDataBlob = new JsonDataBlob();
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.registerModule(new AfterburnerModule());
            try {
                return objectMapper.writeValueAsString(jsonDataBlob);
            } catch(Exception e) {
                e.printStackTrace();
            }
            return "";          
        }               
}

pom.xml looks like below:-

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hello</groupId>
    <artifactId>world</artifactId>
    <version>0.0.1</version>
    <packaging>bundle</packaging>
    <name>Hello World</name>
    <dependencies>
        <!-- OSGi -->
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160212</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.2</version>
        </dependency>

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

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-afterburner</artifactId>
            <version>2.7.1</version>
        </dependency>



    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <excludes>
                        <exclude>**/com/hello/main/*</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.4.0</version>
                <inherited>true</inherited>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Bundle-Activator>com.hello.world.HelloWorldActivator</Bundle-Activator>
                        <Import-Package>*;resolution:=optional</Import-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The java object which I am trying to convert to json is a simple object as shown below:-

package com.hello.world;
public class JsonDataBlob {
    private String add1 = "JP Naagar";
    private String add2 = "";
    private int shippartagent = 1;

    public String getAdd1() {
        return add1;
    }

    public void setAdd1(String add1) {
        this.add1 = add1;
    }

    public String getAdd2() {
        return add2;
    }

    public void setAdd2(String add2) {
        this.add2 = add2;
    }

    public int getShippartagent() {
        return shippartagent;
    }

    public void setShippartagent(int shippartagent) {
        this.shippartagent = shippartagent;
    }
}


Whenever I am trying to install the bundle I am getting the below exception:-

2016-05-07 15:36:48,986 | WARN  | x-6.1-2.0/deploy | fileinstall                      | 7 - org.apache.felix.fileinstall - 3.5.0 | Error while starting bundle: file:/Users/debraj/Downloads/apache-servicemix-6.1-2.0/deploy/world-0.0.1.jar
org.osgi.framework.BundleException: Activator start error in bundle world [239].
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:2196)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1245)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1217)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:509)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:358)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:310)[7:org.apache.felix.fileinstall:3.5.0]
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/module/afterburner/AfterburnerModule
        at java.lang.Class.getDeclaredConstructors0(Native Method)[:1.8.0_77]
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)[:1.8.0_77]
        at java.lang.Class.getConstructor0(Class.java:3075)[:1.8.0_77]
        at java.lang.Class.newInstance(Class.java:412)[:1.8.0_77]
        at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4336)
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:2141)
        ... 7 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.module.afterburner.AfterburnerModule not found by world [239]
        at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)[:1.8.0_77]
        ... 13 more

All the required Jackson bundles are installed in Karaf:-

karaf@root>bundle:list | grep Jackson
123 | Active    |  50 | 2.6.2                              | Jackson-core                                   
125 | Active    |  50 | 2.6.2                              | Jackson-annotations                            
238 | Installed |  80 | 2.7.1                              | Jackson-module-Afterburner                     
karaf@root>bundle:list | grep jackson
124 | Active    |  50 | 2.6.2                              | jackson-databind  

Everything works fine if I just comment out the below line:-

objectMapper.registerModule(new AfterburnerModule());

I have placed the required code in github

I have also reported the same issue here . as I was not sure where to report issues. Let me know I will close one of the issue.

Jackson XmlElementWrapper handling with USE_WRAPPER_NAME_AS_PROPERTY_NAME fails if have 2 fields using same XmlElement name/class

Encountered a problem updating from org.codehaus.jackson 1.9.2.
We use name value from XmlElementWrapper rather than the name from XmlElement as the JSON property name for an element. In some cases, we have 2 fields which wrap lists of the same objects. This breaks with current code, because there is an intermediate stage where the code still uses the name from XmlElement (see JaxbAnnotationIntrospector.findJaxbPropertyName) even though MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME is set.

package com.fasterxml.jackson.module.jaxb.misc;

import java.util.*;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jaxb.BaseJaxbTest;

/**
 * Unit tests to verify handling of @XmlElementWrapper annotation.
 */
public class XmlElementWrapperTest extends BaseJaxbTest
{
    static class HasTwoFieldsWithSameElementName {
        @XmlElementWrapper(name = "keep")
        @XmlElement(name = "value")
        public List<Integer> keepList = Arrays.asList(1,2);

        @XmlElementWrapper(name = "purge")
        @XmlElement(name = "value")
        public List<Integer> purgeList = Arrays.asList(3,4);

        public HasTwoFieldsWithSameElementName() { }

        public HasTwoFieldsWithSameElementName(
                List<Integer> keep, List<Integer> purge) {
            keepList = keep;
            purgeList = purge;
        }

        public List<Integer> getKeepList() {
            return keepList;
        }

        public List<Integer> getPurgeList() {
            return purgeList;
        }
    }

    /** tests that if using wrapper name as property name, this works
     * even if 2 fields use the same element name with the same class
     */
    public void testWrapperWith2Collections() throws Exception
    {
        ObjectMapper mapper = getJaxbMapperBuilder()
                .enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)
                .build();
        HasTwoFieldsWithSameElementName obj =
            new HasTwoFieldsWithSameElementName(Arrays.asList(1, 2),
                    Arrays.asList(3, 4));

        String json = mapper.writeValueAsString(obj);
        System.out.println("JSON == "+json);

        assertEquals("{\"keep\":[1,2],\"purge\":[3,4]}", json);
        HasTwoFieldsWithSameElementName result =
            mapper.readValue(json, HasTwoFieldsWithSameElementName.class);
        assertNotNull("keepList", result.keepList);
        assertEquals("keepList size", 2, result.keepList.size());
        assertEquals("keepList first entry", 1, result.keepList.iterator().next().intValue());
    }
}

Running this test gives:

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.008 sec <<< FAILURE! - in com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest
testWrapperWith2Collections(com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest)  Time elapsed: 0.008 sec  <<< ERROR!
com.fasterxml.jackson.databind.JsonMappingException: Conflicting getter definitions for property "value": com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest$HasTwoFieldsWithSameElementName#getKeepList(0 params) vs com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest$HasTwoFieldsWithSameElementName#getPurgeList(0 params)
	at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getGetter(POJOPropertyBuilder.java:427)
	at com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition.getAccessor(BeanPropertyDefinition.java:181)
	at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getPrimaryMember(POJOPropertyBuilder.java:563)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._renameWithWrappers(POJOPropertiesCollector.java:864)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:322)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getJsonValueAccessor(POJOPropertiesCollector.java:175)
	at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findJsonValueAccessor(BasicBeanDescription.java:236)
	at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(BasicSerializerFactory.java:322)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:207)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:169)
	at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:839)
	at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:639)
	at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:469)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:231)
	at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:1771)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:1723)
	at com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest.testWrapperWith2Collections(XmlElementWrapperTest.java:55)

Unmarshalling a @JacksonXmlText property fails if there is a all-args-constructor (even a private one)

See this test case:

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
import org.junit.Test;

import java.beans.ConstructorProperties;
import java.io.IOException;
import javax.xml.bind.annotation.XmlAttribute;

public class JacksonXmlTextTest {

    private static final String XML = "<ROOT><CHILD attr=\"attr_value\">text</CHILD></ROOT>";

    @JacksonXmlRootElement(localName = "ROOT")
    public static class Root {
        @JacksonXmlProperty(localName = "CHILD") final Child child;

        public Root(Child child) {
            this.child = child;
        }

        public Child getChild() {
            return child;
        }
    }

    public static class Child {
        @XmlAttribute
        String attr;

        @JacksonXmlText
        String el;

        public Child() {
        }

        @ConstructorProperties({"attr", "el"})
        private Child(String attr, String el) {
            this.attr = attr;
            this.el = el;
        }

        public String getAttr() {
            return this.attr;
        }

        public String getEl() {
            return this.el;
        }

        public void setAttr(String attr) {
            this.attr = attr;
        }

        public void setEl(String el) {
            this.el = el;
        }
    }

    @JacksonXmlRootElement(localName = "ROOT")
    public static class RootWithoutConstructor {
        @JacksonXmlProperty(localName = "CHILD") final ChildWithoutConstructor child;

        @ConstructorProperties({"child"})
        public RootWithoutConstructor(ChildWithoutConstructor child) {
            this.child = child;
        }

        public ChildWithoutConstructor getChild() {
            return child;
        }
    }

    public static class ChildWithoutConstructor {
        @XmlAttribute
        String attr;

        @JacksonXmlText
        String el;

        public String getAttr() {
            return this.attr;
        }

        public String getEl() {
            return this.el;
        }

        public void setAttr(String attr) {
            this.attr = attr;
        }

        public void setEl(String el) {
            this.el = el;
        }
    }

    @Test
    public void verifyJacksonXmlTextIsUnmarshalled() throws IOException {
        final XmlMapper mapper = new XmlMapper(new JacksonXmlModule());
        assertThat(
            mapper.readValue(XML, Root.class).getChild().el,
            is("text")
        );
    }

    @Test
    public void verifyJacksonXmlTextIsUnmarshalledWithoutConstructor() throws IOException {
        final XmlMapper mapper = new XmlMapper(new JacksonXmlModule());
        assertThat(
            mapper.readValue(XML, RootWithoutConstructor.class).getChild().el,
            is("text")
        );
    }

}

verifyJacksonXmlTextIsUnmarshalled() fails. verifyJacksonXmlTextIsUnmarshalledWithoutConstructor() succeeds.

What is new in new version with afterburner?

In my project we use default jackson-module-afterburner version is 2.8.10, but somebody use version for 2.9.5 .
My question is how different with new version๏ผŸ
I dont found any useful information in docs, Thanks a lot.

Make mr bean implement `clone()` method

Cloning of the internal structure (HashMap I presume) would be possible just like equals and hashCode have no been dealt with. If there is an abstract implementation already present then the call to super will take care of that. Support of course only works when Cloneable interface is present.

Use @XmlSchemaType hints

Hi,
Using an XmlJavaTypeAdapter to convert types works fine when serializing to XML.
The problem comes up with JSON serialization and types that are shouldn't really be serialized to string when they are actually boolean or number, as can be seen in an existing test.

Even though the object is long, it ends up serialized as string in JSON.
I'm thinking that the @XmlSchemaType hint should help here, if it would be used.

`ALLOW_COERCION_OF_SCALARS` ignored deserializing scalars with Afterburner

Let's look at deserializing an integer field, for example.

The code path in afterburner ends up here:

int v = p.hasToken(JsonToken.VALUE_NUMBER_INT) ? p.getIntValue() : _deserializeInt(p, ctxt);

If the value being deserialized is not a VALUE_NUMBER_INT, then the code delegates to _deserializeInt which will always attempt to coerce a VALUE_STRING to an integer:

if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = p.getText().trim();
if (_hasTextualNull(text)) {
return 0;
}
try {
int len = text.length();
if (len > 9) {
long l = Long.parseLong(text);
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw ctxt.weirdStringException(text, Integer.TYPE,
"Overflow: numeric value ("+text+") out of range of int ("+Integer.MIN_VALUE+" - "+Integer.MAX_VALUE+")");
}
return (int) l;
}
if (len == 0) {
return 0;
}
return NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
throw ctxt.weirdStringException(text, Integer.TYPE, "not a valid int value");
}
}

This code path should only be enabled if MapperFeature.ALLOW_COERCION_OF_SCALARS is enabled.

Similarly, this check should be performed when attempting to deserialize other scalar types like boolean and long.

Implement `equals()` method

It would make sense for mr-bean module to implement equals(), at least for interfaces, and for abstract classes that do not define equals() for target type.

Basic implementation should simply compare all logical properties using the typical implementation that an IDE would produce (field-by-field comparison).

[guice] ObjectMapperModule doesn't allow configuring JsonFactory to use

Hi,

ObjectMapperProvider, the static private class, used by ObjectMapperModule inside, is doing internally among other stuff:
final ObjectMapper mapper = new ObjectMapper();
which doesn't allow us to inject a JsonFactory into into the mapper,
e.g. new ObjectMapper(MongoBsonFactory.createFactory()), like it would be needed in case of using jongo for example.

Can you solve this issue, please?

Thank you,
Bogdan

Afterburner `MyClassLoader#loadAndResolve()` is not idempotent when `tryToUseParent` is true

The MyClassLoader used by the Afterburner module checks to see if it has already loaded a class with the given name and short-circuits, but it does not check whether the parent class loader has already loaded the requested class:

// First things first: just to be sure; maybe we have already loaded it?
Class<?> old = findLoadedClass(className.getDottedName());
if (old != null) {
    return old;
}

ClassLoader#defineClass fails with a LinkageError when a class with the same name has already been defined, so the second time that a generated class with the same base name and bytecode is loaded by afterburner, the attempt to define it on the parent class loader will fail and silently fall through to define it on the MyClassLoader itself. This will succeed, and produce no ill effect in most circumstances.

try {
    Method method = ClassLoader.class.getDeclaredMethod("defineClass",
            new Class[] {String.class, byte[].class, int.class,
            int.class});
    method.setAccessible(true);
    return (Class<?>)method.invoke(getParent(),
            className.getDottedName(), byteCode, 0, byteCode.length);
} catch (Exception e) {
    // Should we handle this somehow?
}

However, when the bean class being deserialized is a private inner class (as is commonly seen in bean classes generated by the Immutables framework), it is necessary that the class loader into which afterburner injects its custom instantiator class be the same as the class loader which loaded the private inner class itself, or else an IllegalAccessError will occur during deserialization.

Under typical operations, afterburner will only generate a specific custom instantiator class once, but when two threads, each using an ObjectMapper with the same ClassLoader instance both attempt to deserialize the same type at the same time (for the first time), both threads can end up trying to define the same custom instantiator bytecode at almost exactly the same time. The first thread to make the attempt will define the new class on the "parent" class loader. The second attempt will fail to define the (now already existing) class on the parent class loader, and will fall back to defining it on the MyClassLoader itself. If the class being deserialized is a private inner class, the second thread will subsequently throw an IllegalAccessError during deserialization, and all further attempts to deserialize that type will also throw the same error.

I believe that MyClassLoader#loadAndResolve should first check to see if the parent class loader has loaded the requested class, then proceed with the logic of the method as written. Something like this at the top of the method:

Class<?> old = null;
if (_cfgUseParentLoader && getParent() != null) {
	try {
	    Method method = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
	    method.setAccessible(true);
	    old = (Class<?>)method.invoke(getParent(), className.getDottedName());
	} catch (Exception e) {
	    // Fall through
	}
}
if (old != null) {
    return old;
}
old = findLoadedClass(className.getDottedName());
if (old != null) {
    return old;
}

(mrbean) Problem deserializing Long into Calendar with mrBean

I have a situation where I am trying to deserialize a timestamp (that was serialized by Jackson) into a Calendar. This works fine out of the box with Jackson. However, if I register the MrBean module with my ObjectMapper then it fails to deserialize. From what I have been able to figure out on my own when MrBean is not present Jackson uses DateDeserializer to convert the Long into a Calendar instance. When MrBean is present then an AbstractTypeResolver is added to the ObjectMapper and instead BeanDeserializer is used to convert the Long into a Calendar instance but that fails.

It seems like this would be a common scenario so I'm wondering if I'm configuring something incorrectly. I've included some more details below along with an example project recreating the issue. Please let me know if you need any more information from me.

Jackson Version: 2.6.5
Operating System: Windows
Example Project: https://github.com/klieber/jackson-mrbean-issue
Example Stacktrace:

java.lang.IllegalArgumentException: Can not instantiate value of type [simple type, class com.fasterxml.jackson.module.mrbean.generated.java.util.Calendar] from Long integral number (1463620778163); no single-long-arg constructor/factory method
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.klieber.example.MockObject["expiration"])
        at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3459)
        at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3378)
        at com.klieber.example.ObjectMapperTest.testConvertValueWithMrBean(ObjectMapperTest.java:39)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.fasterxml.jackson.module.mrbean.generated.java.util.Calendar] from Long integral number (1463620778163); no single-long-arg constructor/factory method
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.klieber.example.MockObject["expiration"])
        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
        at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:878)
        at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromLong(StdValueInstantiator.java:320)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1144)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:147)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:136)
        at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
        at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3454)
        ... 31 more

Consider use of Java 8 `LambdaMetafactory` for Afterburner getter/setter access

As per:

https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html

it seems like there is a way to actually get near-static access for getters, without (explicit) code generation, using Java 8 added class LambdaMetafactory. Whether it will actually work out or not remains to be seen -- and, if it does, could it actually be added in jackson-databind? -- but seems like a promising lead. While mechanism is probably not enough to cover all code generation needs (field access, constructor calls), getter/setter access is significant on its own.

FAIL_ON_NULL_FOR_PRIMITIVES not working with AfterburnerModule

Hi,
I've tried to used AfterburnerModule with Jackson DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES but it look like it doesn't work for long and int primitives. Double works fine.

Here is the code scratch to reproduce the problem.

class Test
{
    public static void main(String[] args)
    {
        final ObjectMapper mapper = new ObjectMapper()
                .registerModule(new AfterburnerModule())
                .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
        try {
            final LongWrapper longWrapper = mapper.readValue("{\"value\": null}", LongWrapper.class);
            System.out.println(longWrapper);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class LongWrapper
    {
        public long value;
    }
}

I'm using Jackson 2.9.1 with Dropwizard 1.2.0.

Repository artifact for non-shaded MrBean dependency

ByteBuddy already shades the usually no so backward compatible ASM and I'd really with to be able to utilize ByteBuddy's latest fixes with MrBean in the future. Would it be possible to get rid of the shading all-to-gether and trust ByteBuddy to do the job properly or at least have a non-shaded version of the library available as well. I don't think that having ByteBuddy shaded (and therefore having ASM re-shaded) is beneficial and I believe this is just a leftover from the transition.

PS. To me it's not an issue which of the .jars is the default one but since it's a major release, perhaps the shaded one should actually be the one behind classifier.

PPS. I wonder why ByteBuddy doesn't provide a I-know-what-I'm-doing variant of the .jar. Only the shaded one is available. This should not be an issue since ASM isn't directly used anymore or is it. If it is then I'd would've been nice to have non-shaded versions of both of the libraries and have the shading done once for both. This would of course render the non-shaded version quite useless due to ASM being known to backward compatible in quite error prone way, but I trust that everything is done or could be done via ByteBuddy

Edit: There is a byte-buddy-dep version of the library that doesn't have any shaded libs in it.

Paranamer exception

In case that I have empty class that extends base one e.g.:

public class Child extends Parent {
public Child(int version){ super(version); }
}

public abstract class Parent implements CommandMessage {
public final int version;
public Parent(int version){ this.version=version;}
}

public interface CommandMessage extends Message {
}

public interface Message {
}

and if I try to use paranamer for Child class, I get an exception - no default constructor; As soon as I add one new field to Child class, paranamer works OK.

Jackson emitting Jaxby @XmAttribute annotated property as an element when a bean serializer modifier is added.

When I register a custom bean serializer modifier with a mapper (version 2.9.6), like so:

      final SimpleModule module = new SimpleModule();
      module.setSerializerModifier(new CustomSerializerModifier(serializationConfig));
      xmlMapper.registerModule(module);

And also register the Jaxby module (or set annotation introspector ... have tried multiple means).

      xmlMapper.registerModule(new JaxbAnnotationModule());

I get an output that looks like this:

<XmlAnnotated>
	<CustomerAge>0</CustomerAge>
	<CustomerId>0</CustomerId>
... other elements
</XmlAnnotated>

instead of the expected:

<XmlAnnotated CustomerAge=\"0\" CustomerId=\"0\">
... other elements
</XmlAnnotated>"

Class defined as:

/**
 * XMLAnnotated class for testing serialization.
 */
@XmlRootElement
public class XmlAnnotated {

  private String custName;
  private int custAge;
  private int custId;
  private Element anyElement;

  /**
   * getCustName.
   */
  public String getCustName() {
    return custName;
  }

  /**
   * getCustname.
   */
  @XmlElement(name = "UserName", required = true)
  public void setCustName(final String custName) {
    this.custName = custName;
  }

  /**
   * getCustAge.
   */
  @XmlAttribute(name = "CustomerAge", required = true)
  public int getCustAge() {
    return custAge;
  }

  /**
   * getCustAge.
   */
  @XmlElement
  public void setCustAge(final int custAge) {
    this.custAge = custAge;
  }

  /**
   * getCustId.
   */
  @XmlAttribute(name = "CustomerId", required = true)
  public int getCustId() {
    return custId;
  }

  /**
   * setCustId.
   */
  @XmlAttribute
  public void setCustId(final int custId) {
    this.custId = custId;
  }

  /**
   * Gets the Any element parent container.
   */
  public Element getAnyElement() {
    return anyElement;
  }

  /**
   * Set the Any element.
   */
  @XmlElement
  public void setAnyElement(final Element anyElement) {
    this.anyElement = anyElement;
  }
}

If I remove the modifier then Jackson behaves as expected. I can see the annotation introspector is set in both cases appropriately but unsure as of yet why adding the modifier prevents the desired behavior.

It looks like it also rewrites the name correctly to the value in the XmlAttribute tag, it's just the transform to an attribute that is missing (from what I can tell).

Afterburner` SuperSonicBeanDeserializer` does not handle JSON Object valued Object Ids (like json)

I am attempting to use something like https://github.com/jsog/jsog-jackson so that a .Net client (through a Jackson-using API endpoint) can process references (with "$id" as the @JsonIdentityInfo property value and "$ref" for the JSON Reference). When Afterburner is used, this doesn't work because the SuperSonicBeanDeserializer.deserializeFromObject doesn't check with the _objectIdReader to see if that should be used.

The databind BeanDeserializer has a check for the _objectIdReader (per databind#622 in comment)

public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException
{
    /* 09-Dec-2014, tatu: As per [databind#622], we need to allow Object Id references
     *   to come in as JSON Objects as well; but for now assume they will
     *   be simple, single-property references, which means that we can
     *   recognize them without having to buffer anything.
     *   Once again, if we must, we can do more complex handling with buffering,
     *   but let's only do that if and when that becomes necessary.
     */
    if ((_objectIdReader != null) && _objectIdReader.maySerializeAsObject()) {
        if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)
                && _objectIdReader.isValidReferencePropertyName(p.getCurrentName(), p)) {
            return deserializeFromObjectId(p, ctxt);
        }

The SuperSonicBeanDeserializer overrides BeanDeserializer.deserializeFromObject and doesn't have a similar check.

Utilize ByteBuddy's InjectionClassLoader instead of AbstractTypeMaterializer.MyClassLoader

ByteBuddy is able to either wrap or inject defined classes to given classloader whereas MyClassLoader is merely a wrapper. The injection approach would reduce end-user's stack of classloaders by eliminating the need for yet-another classloader.

In #62 I suggested that non-shaded version would be provided because then I could construct the materializer using a non-sealed InjectionClassLoader that contains some custom made abstract classes that I have crafted using ByteBuddy. For those using the shaded the approach would be the more familiar classloader wrapping. For me to start calling the shaded version of ByteBuddy would be rather cumbersome.

[guice] fail to inject MapBinder

MapBinder

final class Configure {
    @Inject
    private Map<String, WorkspaceFactory> factoryMap;
    ... ...
}

When I want to deserialize json: Configure configure = mapper.readValue(file, Configure.class);. I get the following errors:

Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for java.util.Map was bound.
  while locating java.util.Map

1 error
	at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1075)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1081)
	at com.fasterxml.jackson.module.guice.GuiceInjectableValues.findInjectableValue(GuiceInjectableValues.java:20)
	at com.fasterxml.jackson.databind.DeserializationContext.findInjectableValue(DeserializationContext.java:382)
	at com.fasterxml.jackson.databind.deser.impl.ValueInjector.findValue(ValueInjector.java:45)
	at com.fasterxml.jackson.databind.deser.impl.ValueInjector.inject(ValueInjector.java:51)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.injectValues(BeanDeserializerBase.java:1513)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:354)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2890)

(jaxb) Jackson doesn't wrap properties with XMLElementWrapper

(note: moved from FasterXML/jackson-module-jaxb-annotations#69 filed by @GonenI)

Jackson 2.9.4 with JaxbAnnotationModule Ignores @XMLElementWrapper , and does not add an extra level of wrapping.

For a class looking like this:

@XmlRootElement(name = "revision")
class A {
	private List<Integer> tickets = Arrays.asList(3,4,5);

	@XmlElement(name = "ticket")
	@XmlElementWrapper(name = "tickets")
	public List<Integer> getTickets() {	return tickets; }
}

The expected output, and what Jettison outputs is {"tickets":{"ticket":[3,4,5]}}
Jackson ignores the the @XmlElementWrapper wrapping directive and outputs {"ticket":[3,4,5]}

Failing Unit Test:

@XmlRootElement(name = "revision")
class A {
	private List<Integer> tickets = Arrays.asList(3,4,5);

	@XmlElement(name = "ticket")
	@XmlElementWrapper(name = "tickets")
	public List<Integer> getTickets() {	return tickets; }
}
@XmlRootElement(name = "revision")
class B {
	private List<Integer> tickets = Arrays.asList(3,4,5);

	@XmlElement(name = "ticket")
	public List<Integer> getTickets() {	return tickets; }
}
public class XMLElementWrapperTest {

	@Test
	public void test() throws Exception {
		ObjectMapper mapper = new ObjectMapper();
		JaxbAnnotationModule jaxbAnnotationModule = new JaxbAnnotationModule();
		mapper.registerModule(jaxbAnnotationModule);
    	A a = new A(); B b = new B();
   	    Assert.assertNotEquals(mapper.writeValueAsString(a),mapper.writeValueAsString(b)); // Expected output with Element wrapper is {"tickets":{"ticket":[3,4,5]}}
	}
}

Support for default values

Besides this stackoverflow question, I couldn't really find any information related to this topic but it would be nice to extend the support of default values in Jackson, particularly in the context of the MrBean module.

One option could be using annotations:

interface Person {
  @DefaultValue("default first name")
  String getFirstName();
  @DefaultValue("default last name")
  String getLastName();
}

Another option could be using Java 8 default methods:

interface Person {
  default String getFirstName() { return "default first name"; }
  default String getLastName() { return "default last name"; }
}

Currently, there are two main limitation I see for MrBean:

  1. No possibility to specify default values
  2. No possibility to use Java 8 Optional

`@JsonAppend` causes 'IllegalStateException` `Unsupported annotated member' with `JaxbAnnotationModule`

It seems that using JaxbAnnotationModule causes some problems when using @JsonAppend feature. Example that reproduce the issue:

@Test
public void testJsonAppendWithJaxb() throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JaxbAnnotationModule());
    String json = mapper.writeValueAsString(new Pojo("foo"));
    assertEquals("{\"name\":\"foo\",\"virtual\":\"bar\"}", json);
}

@JsonAppend(props = @JsonAppend.Prop(name = "virtual", value = MyVirtualPropertyWriter.class))
public static class Pojo {

    private final String name;

    public Pojo(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

public static class MyVirtualPropertyWriter extends VirtualBeanPropertyWriter {
    public MyVirtualPropertyWriter() {
    }

    protected MyVirtualPropertyWriter(BeanPropertyDefinition propDef, Annotations contextAnnotations,
            JavaType declaredType) {
        super(propDef, contextAnnotations, declaredType);
    }

    @Override
    protected Object value(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception {
        return "bar";
    }

    @Override
    public VirtualBeanPropertyWriter withConfig(MapperConfig<?> config, AnnotatedClass declaringClass,
            BeanPropertyDefinition propDef, JavaType type) {

        return new MyVirtualPropertyWriter(propDef, declaringClass.getAnnotations(), type);
    }
}

Throws exception:

java.lang.IllegalStateException: Unsupported annotated member: com.fasterxml.jackson.databind.introspect.VirtualAnnotatedMember

	at com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector.findAnnotation(JaxbAnnotationIntrospector.java:1363)
	at com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector.findWrapperName(JaxbAnnotationIntrospector.java:453)
	at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findWrapperName(AnnotationIntrospectorPair.java:435)
	at com.fasterxml.jackson.databind.util.SimpleBeanPropertyDefinition.getWrapperName(SimpleBeanPropertyDefinition.java:215)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.<init>(BeanPropertyWriter.java:215)
	at com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter.<init>(VirtualBeanPropertyWriter.java:57)
	at com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter.<init>(VirtualBeanPropertyWriter.java:35)
	at com.test.TestVirtualProperties$MyVirtualPropertyWriter.<init>(TestVirtualProperties.java:52)
	at com.test.TestVirtualProperties$MyVirtualPropertyWriter.withConfig(TestVirtualProperties.java:64)
	at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector._constructVirtualProperty(JacksonAnnotationIntrospector.java:911)
	at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.findAndAddVirtualProperties(JacksonAnnotationIntrospector.java:852)
	at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findAndAddVirtualProperties(AnnotationIntrospectorPair.java:546)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:407)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:282)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:234)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:168)
	at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1308)
	at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1258)
	at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:500)
	at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:698)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:270)
	at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)
	at com.test.TestVirtualProperties.testJsonAppendWithJaxb(TestVirtualProperties.java:28) <22 internal calls>

Also changing primary and secondary annotation introspector with:

AnnotationIntrospector jacksonAnnIntro = new JacksonAnnotationIntrospector();
AnnotationIntrospector jaxbAnnIntro = new JaxbAnnotationIntrospector();
mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(jacksonAnnIntro, jaxbAnnIntro));

and it does not work.

I tested it with 2.9.1 and 2.8.8.

Afterburner class generation isn't compatible with PowerMock >=1.7.0, causing class cast exceptions

Doing powermock tests with Afterburner optimization are causing "cannot cast" exceptions for both mutator and accessor generated classes.

This happens because when afterburner is creating the methods, it is by mistaken returning an incompatible class from a upper classloader, which isn't compatible.

This happens at generateAccessorClass function,
In old powermock versions when a class was not found, it used to throw a ClassNotFoundException, but now it is returning (correctly?) the class if it exists in the system class loader. This also happens in powermock 2.x branch.

I'm not 100% sure the problem is only at fasterxml afterburner code, powermock could be partially mistaken as well.

But, I think the way to solve this bug correctly in Afterburner is to make sure in PropertyAccessorCollector and PropertyMutatorCollector that the class which is returned by classLoader.loadClass is indeed compatible with its matching class interface (BeanPropertyAccessor or BeanPropertyMutator.class), and if not to generate it as usual (classLoader.loadAndResolve)

The current situation makes fasterxml+afterburner+powermock above 1.7.0 to fail when your project have some of tests with powermock and some without.
The only way to mitigate it is either disable afterburner, or make sure all unit-tests run in separate jvms (slows down the unit-tests)

And since all powermock 2.x releases has this incompatibility as well, it means there's no Java11 compatible version of powermock which could run those unit-tests without the mitigations above.

attached unit-test to show the failure, it will first execute Test1 which will create the afterburner accessors at the system class loader, and then Test2 (with powermock/MockClassLoader) will throw that cast exception.

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.IOException;

@RunWith(Enclosed.class)
public class TestFailure {
  private static class MyObject {
    @JsonProperty("object")
    public String object;
  };

  private static void doit() throws IOException {
    ObjectMapper objectMapper =
            new ObjectMapper();

    // causes the exception of:
    // java.lang.IllegalStateException: Failed to generate accessor class 'TestFailure$MyObject$Access4JacksonSerializerac50bfc2': TestFailure$MyObject$Access4JacksonSerializerac50bfc2 cannot be cast to com.fasterxml.jackson.module.afterburner.ser.BeanPropertyAccessor
    objectMapper.registerModule(new AfterburnerModule());

    MyObject o = new MyObject();
    objectMapper.readValue(objectMapper.writeValueAsString(o), MyObject.class);
  }

  @RunWith(PowerMockRunner.class)
  public static class Test2 {
    @Test
    public void testWithPowerMock() throws IOException {
      doit();
    }
  }

  public static class Test1 {
    @Test
    public void testWithoutPowerMock() throws IOException {
      doit();
    }
  }
}

pom (changing powermock version to 1.7.0RC4 solves it, as they fixed a bug and caused this regression in this commit):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>testfailure</groupId>
    <artifactId>testfailure</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <powermock.version>1.7.0</powermock.version>
        <fasterxml.jackson.version>2.9.6</fasterxml.jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-afterburner</artifactId>
            <version>${fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jaxb-annotations</artifactId>
            <version>${fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.activation</groupId>
            <artifactId>javax.activation</artifactId>
            <version>1.2.0</version>
        </dependency>
    </dependencies>
</project>

`@XmlElements` does not work with `@XmlAccessorType(XmlAccessType.NONE)`

I cannot get working @XmlElements and @XmlAccessorType(XmlAccessType.NONE) in Jackson 2.9.5. It ignores the field during serialization when I add XmlAccessorType annotation with NONE value.

@XmlElement works fine.

public class NoneAccessTest extends BaseJaxbTest {

    static class Foo {
        private String foo;

        public Foo() { }
        public Foo(String foo) { this.foo = foo; }

        public String getFoo() {
            return foo;
        }

        public void setFoo(String foo) {
            this.foo = foo;
        }
    }

    @XmlAccessorType(XmlAccessType.NONE)
    static class NoneAccessBean
    {
        @XmlElements({
                @XmlElement(type=Foo.class, name="foo")
        })
        public Object object;

        @XmlElement
        public Object other;

        public NoneAccessBean() { }
        public NoneAccessBean(Object o) { object = o; }
        public NoneAccessBean(Object o, Object b) {
            object = o;
            other = b;
        }
    }

    public void testNoneAccessWithXmlElements() throws Exception {
        NoneAccessBean input = new NoneAccessBean(new Foo("foo"));

        ObjectMapper mapper = getJaxbMapper();
        String str = mapper.writeValueAsString(input);
        assertEquals("{\"object\":{\"foo\":{\"foo\":\"foo\"}},\"other\":null}", str);
    }
}

Result is:

Expected :{"object":{"foo":{"foo":"foo"}},"other":null}
Actual   :{"other":null}

It used to work at least in 2.6 and seems to be a valid scenario.

Java 9 warning for Afterburner

When compiling a Dropwizard project with Java 9, Jackson compilation throws the following error,

WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.fasterxml.jackson.module.afterburner.util.MyClassLoader (file:/Users/user/Code/application.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int) WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.module.afterburner.util.MyClassLoader WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release

(mrbean) Problem with `Optional<T>`, `AtomicReference<T>` valued properties

Hello,

I'd really like to use your mrbean module, but it does not seem to support java 8 optionals. Is this correct? Do you have planned adding support for this?

I've created a small testcase and that does not seem to work. It throws an GenericSignatureFormatError...
`

import java.util.Optional;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.http.MockHttpInputMessage;

import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.module.mrbean.MrBeanModule;

public class ReadOptionalTest {

    public static final String json = "{\"string\":\"value\",\"optionalString\":\"anotherValue\"}";
    public static interface MyInterface {

        String getString();
        Optional<String> getOptionalString();
    }
    private MappingJackson2HttpMessageConverter messageConverter;

    @Before
    public void setup() {
        this.messageConverter = new MappingJackson2HttpMessageConverter();
        this.messageConverter.getObjectMapper().registerModules(new Jdk8Module(), new MrBeanModule());
    }

    @Test
    public void testReadObject() throws Exception {
        final MyInterface object = (MyInterface) messageConverter.read(MyInterface.class, new MockHttpInputMessage(json.getBytes()));
        Assert.assertNotNull(object);
    }
}

`

Best regards,
Thomas

NPE from MrBean when `get()` or `set()` is though as property

java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at java.lang.String.charAt(String.java:658)
	at com.fasterxml.jackson.module.mrbean.BeanBuilder.decap(BeanBuilder.java:350)
	at com.fasterxml.jackson.module.mrbean.BeanBuilder.getPropertyName(BeanBuilder.java:192)
	at com.fasterxml.jackson.module.mrbean.BeanBuilder.addGetter(BeanBuilder.java:209)
	at com.fasterxml.jackson.module.mrbean.BeanBuilder.implement(BeanBuilder.java:87)

I'm getting an NPE from decap function that assumes strings to be non-empty as property names should be. The addGetter (and addSetter) should check that methodName is either more than 3 or 2 chars long depending on the prefix so that cases like introducing a java.util.function.Supplier also work

                String methodName = m.getName();
                int argCount = m.getParameterTypes().length;
                if (argCount == 0) { // getter?
                    if (methodName.startsWith("get") || methodName.startsWith("is") && returnsBoolean(m)) {
                        addGetter(ctxt, m);
                        continue;
                    }
                } else if (argCount == 1 && methodName.startsWith("set")) {
                    addSetter(ctxt, m);
                    continue;
                }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.