mock-server / mockserver

MockServer enables easy mocking of any system you integrate with via HTTP or HTTPS with clients written in Java, JavaScript and Ruby. MockServer also includes a proxy that introspects all proxied traffic including encrypted SSL traffic and supports Port Forwarding, Web Proxying (i.e. HTTP proxy), HTTPS Tunneling Proxying (using HTTP CONNECT) and SOCKS Proxying (i.e. dynamic port forwarding).
http://mock-server.com
Apache License 2.0
4.57k stars 1.07k forks source link

Jackson reports "Conflicting getter definitions" when serializing Parameter #127

Closed trevorr closed 9 years ago

trevorr commented 9 years ago

Parameter indirectly extends Not, which implements both isNot() and getNot().

import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;

import org.junit.Test;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.Parameter;

public class TestCase {

    private final ClientAndServer mockServer = new ClientAndServer();

    @Test
    public void test() throws Exception {
        mockServer.when(request().withQueryStringParameters(new Parameter("a", "b"))).respond(
                response("ok"));
    }
}

throws:

com.fasterxml.jackson.databind.JsonMappingException: Conflicting getter definitions for property "not": org.mockserver.client.serialization.model.NotDTO#getNot(0 params) vs org.mockserver.client.serialization.model.NotDTO#isNot(0 params) (through reference chain: org.mockserver.client.serialization.model.ExpectationDTO["httpRequest"]->com.google.common.collect.TransformingRandomAccessList[0])
    at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:838)
    at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:387)
    at com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.findAndAddSerializer(PropertySerializerMap.java:38)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase._findAndAddDynamic(AsArraySerializerBase.java:270)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:96)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:21)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:186)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:118)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1819)
    at com.fasterxml.jackson.core.base.GeneratorBase.writeObject(GeneratorBase.java:259)
    at com.fasterxml.jackson.core.JsonGenerator.writeObjectField(JsonGenerator.java:1114)
    at org.mockserver.client.serialization.serializers.request.HttpRequestDTOSerializer.serialize(HttpRequestDTOSerializer.java:33)
    at org.mockserver.client.serialization.serializers.request.HttpRequestDTOSerializer.serialize(HttpRequestDTOSerializer.java:14)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:569)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:597)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:118)
    at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:681)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:567)
    at org.mockserver.client.serialization.ExpectationSerializer.serialize(ExpectationSerializer.java:26)
    at org.mockserver.client.server.MockServerClient.sendExpectation(MockServerClient.java:146)
    at org.mockserver.client.server.ForwardChainExpectation.respond(ForwardChainExpectation.java:24)
    at TestCase.test(TestCase.java:14)
Caused by: java.lang.IllegalArgumentException: Conflicting getter definitions for property "not": org.mockserver.client.serialization.model.NotDTO#getNot(0 params) vs org.mockserver.client.serialization.model.NotDTO#isNot(0 params)
    at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getGetter(POJOPropertyBuilder.java:190)
    at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getAccessor(POJOPropertyBuilder.java:283)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.removeIgnorableTypes(BeanSerializerFactory.java:682)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanProperties(BeanSerializerFactory.java:561)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:377)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:272)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:217)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:152)
    at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:873)
    at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:833)

I'm using mockserver-netty 3.9.9 and jackson 2.2.3.

trevorr commented 9 years ago

When I hacked my build to use jackson 2.5.2 (the version mockserver-netty specifies), the test passes, for whatever reason. However, it seems like jackson 2.2.3 was correct in that Not shouldn't have two getters. It's not uncommon for other dependencies to want a particular version of jackson, so I'm curious if Not could be fixed to work with older versions.

jamesdbloom commented 9 years ago

This is now fixed.

The main issue is that older versions of Jackson don't seem to understand the different between boolean and Boolean. The isNull() getter is not a valid getter for a Boolean so the error you are getting is a bug in Jackson, however I have managed to work around that and make this issue go away.

It was more complex then you might expect as these functions are used for two main reasons, first is to support serialisation and de-serialization the second is for the matching process. The matchers I don't want to need to have null checks everywhere, however with Jackson I don't want it to serialise out the value when ever it is false. Thus there needs to be two ways of reading the value, one that is null safe and one that will return null. I've simplified the logic to minimise the use and presence of the null safe getter.