palantir / conjure-java

Conjure generator for Java clients and servers
Apache License 2.0
27 stars 43 forks source link

UndertowServiceEteTest handles Jackson 2.17 MismatchedInputException #2331

Closed schlosna closed 2 months ago

schlosna commented 2 months ago

Before this PR

https://github.com/palantir/conjure-java/pull/2164#issuecomment-2253445505

UndertowServerEteTest.testListOfNull is failing because the exception thrown when deserializing a Guava immutable collection with null values changed.

https://github.com/FasterXML/jackson-datatypes-collections/pull/132

com.palantir.logsafe.exceptions.SafeIllegalArgumentException: Failed to parse request due to malformed content: {contentType=application/json, type=TypeMarker{type=com.google.common.collect.ImmutableList<java.lang.String>}}
    at com.palantir.conjure.java.undertow.runtime.Encodings$AbstractJacksonEncoding.lambda$deserializer$1(Encodings.java:110)
    at com.palantir.conjure.java.undertow.runtime.LazilyInitializedEncoding$LazilyInitializedDeserializer.deserialize(LazilyInitializedEncoding.java:108)
    at com.palantir.conjure.java.undertow.runtime.TracedEncoding$TracedDeserializer.deserialize(TracedEncoding.java:129)
    at com.palantir.conjure.java.undertow.runtime.ConjureBodySerDe$EncodingDeserializerRegistry.deserializeInternal(ConjureBodySerDe.java:211)
    at com.palantir.conjure.java.undertow.runtime.ConjureBodySerDe$EncodingDeserializerRegistry.deserialize(ConjureBodySerDe.java:192)
    at com.palantir.product.EteServiceEndpoints$ReceiveListOfStringsEndpoint.handleRequest(EteServiceEndpoints.java:1585)
    at com.palantir.conjure.java.undertow.runtime.ConjureExceptionHandler.handleRequest(ConjureExceptionHandler.java:42)
    at com.palantir.tracing.undertow.TracedStateHandler.handleRequest(TracedStateHandler.java:44)
    at com.palantir.conjure.java.undertow.runtime.LoggingContextHandler.handleRequest(LoggingContextHandler.java:40)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512)
    at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
    at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.NullPointerException: null
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:906)
    at com.google.common.collect.ImmutableList$Builder.add(ImmutableList.java:841)
    at com.google.common.collect.ImmutableList$Builder.add(ImmutableList.java:802)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaImmutableCollectionDeserializer._deserializeContents(GuavaImmutableCollectionDeserializer.java:72)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaImmutableCollectionDeserializer._deserializeContents(GuavaImmutableCollectionDeserializer.java:18)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaCollectionDeserializer.deserialize(GuavaCollectionDeserializer.java:137)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2105)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1481)
    at com.palantir.conjure.java.undertow.runtime.Encodings$AbstractJacksonEncoding.lambda$deserializer$1(Encodings.java:84)
    ... 15 common frames omitted

After this PR

==COMMIT_MSG== UndertowServiceEteTest handles Jackson 2.17 MismatchedInputException

Jackson < 2.17.0 throws NullPointerException resulting in HTTP 400. Jackson >= 2.17.0 throws "MismatchedInputException: Guava Collection of type com.google.common.collect.ImmutableList<java.lang.String> does not accept null values" resulting in HTTP 422.

==COMMIT_MSG==


com.palantir.conjure.java.undertow.runtime.FrameworkException: Failed to deserialize request: {contentType=application/json, type=TypeMarker{type=com.google.common.collect.ImmutableList<java.lang.String>}}
    at com.palantir.conjure.java.undertow.runtime.FrameworkException.unprocessableEntity(FrameworkException.java:50)
    at com.palantir.conjure.java.undertow.runtime.Encodings$AbstractJacksonEncoding.lambda$deserializer$1(Encodings.java:92)
    at com.palantir.conjure.java.undertow.runtime.LazilyInitializedEncoding$LazilyInitializedDeserializer.deserialize(LazilyInitializedEncoding.java:108)
    at com.palantir.conjure.java.undertow.runtime.TracedEncoding$TracedDeserializer.deserialize(TracedEncoding.java:129)
    at com.palantir.conjure.java.undertow.runtime.ConjureBodySerDe$EncodingDeserializerRegistry.deserializeInternal(ConjureBodySerDe.java:211)
    at com.palantir.conjure.java.undertow.runtime.ConjureBodySerDe$EncodingDeserializerRegistry.deserialize(ConjureBodySerDe.java:192)
    at com.palantir.product.EteServiceEndpoints$ReceiveListOfStringsEndpoint.handleRequest(EteServiceEndpoints.java:1585)
    at com.palantir.conjure.java.undertow.runtime.ConjureExceptionHandler.handleRequest(ConjureExceptionHandler.java:42)
    at com.palantir.tracing.undertow.TracedStateHandler.handleRequest(TracedStateHandler.java:44)
    at com.palantir.conjure.java.undertow.runtime.LoggingContextHandler.handleRequest(LoggingContextHandler.java:40)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512)
    at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
    at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Guava `Collection` of type `com.google.common.collect.ImmutableList<java.lang.String>` does not accept `null` values
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 2]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1767)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1541)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaImmutableCollectionDeserializer._tryToAddNull(GuavaImmutableCollectionDeserializer.java:121)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaImmutableCollectionDeserializer._deserializeContents(GuavaImmutableCollectionDeserializer.java:74)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaImmutableCollectionDeserializer._deserializeContents(GuavaImmutableCollectionDeserializer.java:18)
    at com.fasterxml.jackson.datatype.guava.deser.GuavaCollectionDeserializer.deserialize(GuavaCollectionDeserializer.java:138)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2125)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1501)
    at com.palantir.conjure.java.undertow.runtime.Encodings$AbstractJacksonEncoding.lambda$deserializer$1(Encodings.java:84)
    ... 15 common frames omitted

Possible downsides?

As seen by the unit test, requests with null elements for collections that do not support nulls will result in HTTP 422 Unprocessable Content rather than HTTP 400 Bad Request.

pkoenig10 commented 2 months ago

I also don't think we want to merge into the roomba/jackson-canary branch.

schlosna commented 2 months ago

I also don't think we want to merge into the roomba/jackson-canary branch.

Updated to target the roomba/jackson excavator branch for https://github.com/palantir/conjure-java/pull/2332