Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Parameter names module gets confused with delegate creator which is a static method #1001

Closed
david-bakin opened this issue Nov 12, 2015 · 5 comments
Milestone

Comments

@david-bakin
Copy link

Java 8, with -parameters, Jackson 2.6.3, and using the parameter names module: A deserialization into a pojo that has a single parameter @JsonCreator static method fails because it is apparently looking for a creator property instead of treating it like a delegate creator.

In this example there is no property with the implied name. As a gist, see here, which actually has two problems in it. This is the problem with class D:

package com.bakin_bits;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.testng.annotations.Test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

public class TestJacksonModuleParameterNames
{

    public static class D
    {
        private final String raw1;
        private final String raw2;

        private D(String raw1, String raw2) {
            this.raw1 = raw1;
            this.raw2 = raw2;
        }

        @JsonCreator
        public static D make(String value) {
            String[] split = value.split(":");
            return new D(split[0], split[1]);
        }

        @JsonValue
        public String getMyValue() {
            return raw1 + ":" + raw2;
        }

        @Override
        public boolean equals(Object obj) {
            if (null == obj)
                return false;
            if (this == obj)
                return true;
            if (this.getClass() != obj.getClass())
                return false;

            D rhs = (D) obj;
            return new EqualsBuilder().append(this.raw1, rhs.raw1).append(this.raw2, rhs.raw2).isEquals();
        }

        @Override
        public int hashCode() {
            return new HashCodeBuilder().append(this.raw1).append(this.raw2).toHashCode();
        }

        @Override
        public String toString() {
            return getMyValue();
        }
    }

    @Test(enabled = true)
    public void D_delegate_based_creator_without_parameter_names_module() throws IOException {
        // ARRANGE
        ObjectMapper sut = new ObjectMapper();

        D d = D.make("abc:def");

        // ACT
        String actualJson = sut.writeValueAsString(d);
        D actualD = sut.readValue(actualJson, D.class);

        // ASSERT
        assertThat(actualJson).isEqualTo("\"abc:def\"");
        assertThat(actualD).isEqualTo(d);
    }

    @Test(enabled = true)
    public void D_delegate_based_creator_with_parameter_names_module() throws IOException {
        // ARRANGE
        ObjectMapper sut = new ObjectMapper();
        sut.registerModule(new ParameterNamesModule());

        D d = D.make("abc:def");

        // ACT
        String actualJson = sut.writeValueAsString(d);
        D actualD = sut.readValue(actualJson, D.class);

        // ASSERT
        assertThat(actualJson).isEqualTo("\"abc:def\"");
        assertThat(actualD).isEqualTo(d);
    }
}

Stack trace looks like this:

FAILED: D_delegate_based_creator_with_parameter_names_module
com.fasterxml.jackson.databind.JsonMappingException: Could not find creator property with name 'value' (in class com.bakins_bits.TestJacksonModuleParameterNames$D)
 at [Source: "abc:def"; line: 1, column: 1]
    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.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:542)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:229)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:142)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:403)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:461)
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3838)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3732)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726)
    at com.bakins_bits.TestJacksonModuleParameterNames.D_delegate_based_creator_with_parameter_names_module(TestJacksonModuleParameterNames.java:163)```
@david-bakin
Copy link
Author

Discussed at jackson-users here.

cowtowncoder added a commit that referenced this issue Nov 21, 2015
@cowtowncoder
Copy link
Member

Ok yes, I can reproduce the issue as described. I think this is once more related to need to refactor/rewrite creator handling code; something that I had hoped to do with 2.7, but that was delayed by rewrite of the type handling (which is an older problem, FIFO). Not sure if this could be fixed with something smaller; but at least now there is a unit test that reproduces issue with delegating creator, implicit parameter names (but without requiring parameter names -- I just define custom AnnotationIntrospector).

@jarreds
Copy link

jarreds commented Jun 13, 2016

Any word on a fix for this?

@mihbor
Copy link

mihbor commented Sep 11, 2016

Would benefit from this fix as well.

@cowtowncoder cowtowncoder added this to the 2.8.4 milestone Oct 5, 2016
@cowtowncoder
Copy link
Member

Seems to be fixed; guessing it's due to #1383 fix that goes in 2.8.4 (and was included in 2.7.8)

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

No branches or pull requests

4 participants