dd-trace-java
dd-trace-java copied to clipboard
🐞🐛 Serialization issue when IAST enabled with spring boot + kotlinx serialization
Currently
Given a spring boot application using kotlinx serialization and the dd-java-agent with IAST enabled When we call the endpoint, answering in json Then we get the following error:
500 Server Error for HTTP GET "/bug"
kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Unresolved class: class me.chosante.SerializableByKotlinX$$serializer
at kotlin.reflect.jvm.internal.KClassImpl.reportUnresolvedClass(KClassImpl.kt:329) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.KClassImpl.access$reportUnresolvedClass(KClassImpl.kt:44) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:56) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:47) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:92) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.KClassImpl$Data.getDescriptor(KClassImpl.kt) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.jvm.internal.KClassImpl.getDescriptor(KClassImpl.kt:182) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at kotlin.reflect.full.KClasses.getCompanionObject(KClasses.kt:52) ~[kotlin-reflect-1.5.32.jar!/:1.5.32-release-578(1.5.32)]
at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector.hasCreatorAnnotation(KotlinNamesAnnotationIntrospector.kt:85) ~[jackson-module-kotlin-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector.access$hasCreatorAnnotation(KotlinNamesAnnotationIntrospector.kt:30) ~[jackson-module-kotlin-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector$hasCreatorAnnotation$2.invoke(KotlinNamesAnnotationIntrospector.kt:97) ~[jackson-module-kotlin-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector$hasCreatorAnnotation$2.invoke(KotlinNamesAnnotationIntrospector.kt:97) ~[jackson-module-kotlin-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.module.kotlin.ReflectionCache.checkConstructorIsCreatorAnnotated(ReflectionCache.kt:99) ~[jackson-module-kotlin-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector.hasCreatorAnnotation(KotlinNamesAnnotationIntrospector.kt:97) ~[jackson-module-kotlin-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.AnnotationIntrospector.findCreatorAnnotation(AnnotationIntrospector.java:1413) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findCreatorAnnotation(AnnotationIntrospectorPair.java:786) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findCreatorAnnotation(AnnotationIntrospectorPair.java:786) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreatorParam(POJOPropertiesCollector.java:722) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreatorParam(POJOPropertiesCollector.java:695) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreators(POJOPropertiesCollector.java:644) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:451) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getJsonValueAccessor(POJOPropertiesCollector.java:286) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findJsonValueAccessor(BasicBeanDescription.java:258) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(BasicSerializerFactory.java:393) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:225) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:174) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1503) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1451) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.SerializerProvider._findExplicitUntypedSerializer(SerializerProvider.java:1420) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.hasSerializerFor(DefaultSerializerProvider.java:259) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at com.fasterxml.jackson.databind.ObjectMapper.canSerialize(ObjectMapper.java:3563) ~[jackson-databind-2.15.3.jar!/:2.15.3]
at org.springframework.http.codec.json.AbstractJackson2Encoder.canEncode(AbstractJackson2Encoder.java:131) ~[spring-web-6.0.16.jar!/:6.0.16]
at org.springframework.http.codec.EncoderHttpMessageWriter.canWrite(EncoderHttpMessageWriter.java:114) ~[spring-web-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.method.annotation.AbstractMessageWriterResultHandler.getMediaTypesFor(AbstractMessageWriterResultHandler.java:228) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.method.annotation.AbstractMessageWriterResultHandler.lambda$writeBody$0(AbstractMessageWriterResultHandler.java:164) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.HandlerResultHandlerSupport.getProducibleTypes(HandlerResultHandlerSupport.java:190) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.HandlerResultHandlerSupport.selectMediaType(HandlerResultHandlerSupport.java:141) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.HandlerResultHandlerSupport.selectMediaType(HandlerResultHandlerSupport.java:121) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.method.annotation.AbstractMessageWriterResultHandler.writeBody(AbstractMessageWriterResultHandler.java:164) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at org.springframework.web.reactive.result.method.annotation.ResponseEntityResultHandler.lambda$handleResult$1(ResponseEntityResultHandler.java:190) ~[spring-webflux-6.0.16.jar!/:6.0.16]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[reactor-core-3.5.14.jar!/:3.5.14]
at datadog.trace.instrumentation.springwebflux.server.AdviceUtils$SpanSubscriber.onNext(AdviceUtils.java:89) ~[na:na]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onSubscribe(MonoIgnoreThen.java:134) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:192) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onComplete(MonoFlatMap.java:189) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.Operators.complete(Operators.java:137) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:121) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerNext(FluxConcatMapNoPrefetch.java:258) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) ~[reactor-core-3.5.14.jar!/:3.5.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[reactor-core-3.5.14.jar!/:3.5.14]
[...]
Expectation
Without IAST enabled, it just works (e.g. no error).
How to reproduce
Here is a minimal project including the instructions to reproduce it (3 command lines): https://github.com/CharlyRien/repro-dd-iast-enabled-bug.git
Hello @Chuckame, many thanks for reporting the issue and the and the repo reproducing the issue. We are investigating the issue.
To add more context about the bug comprehension, the jackson serializer tries to serialize the Companion
static field, that have the failing $$serializer
class. Before, this companion field was just skipped.
To add more context about the bug comprehension, the jackson serializer tries to serialize the
Companion
static field, that have the failing$$serializer
class. Before, this companion field was just skipped.
Hello @Chuckame I've created a PR for byte-buddy that should solve the issue, we'll come back to you as soon as we have an updated agent.
Thanks for your patience.
Hello @manuel-alvarez-alvarez many thanks for the reactivity 🚀
Hello @Chuckame,
We've just released the version 1.32.0 that solves the issue you found when enabling IAST with Kotlin serialization.
Many thanks for your patience!