jackson-modules-base icon indicating copy to clipboard operation
jackson-modules-base copied to clipboard

Cannot Deserialize Object with Builder when using AfterBurner and UseValueClassLoader is false

Open austinarbor opened this issue 3 years ago • 6 comments

Description

When using @JsonDeserialize(builder = ...) along with @JsonPojoBuilder, deserialization fails when the Afterburner module is registered with new ObjectMapper().registerModule(new AfterburnerModule().setUseValueClassLoader(false));

Test cases showing the issue: https://github.com/austinarbor/jackson-afterburner-issue/blob/main/src/test/java/dev/aga/model/ContextTest.java

When setUseValueClassLoader(true) everything works as expected

class dev.aga.model.Context$ContextBuilder$Creator4JacksonDeserializer8cf3272c tried to access method 'void dev.aga.model.Context$ContextBuilder.<init>()' (dev.aga.model.Context$ContextBuilder$Creator4JacksonDeserializer8cf3272c is in unnamed module of loader com.fasterxml.jackson.module.afterburner.util.MyClassLoader @2f53b467; dev.aga.model.Context$ContextBuilder is in unnamed module of loader 'app')
java.lang.IllegalAccessError: class dev.aga.model.Context$ContextBuilder$Creator4JacksonDeserializer8cf3272c tried to access method 'void dev.aga.model.Context$ContextBuilder.<init>()' (dev.aga.model.Context$ContextBuilder$Creator4JacksonDeserializer8cf3272c is in unnamed module of loader com.fasterxml.jackson.module.afterburner.util.MyClassLoader @2f53b467; dev.aga.model.Context$ContextBuilder is in unnamed module of loader 'app')
	at dev.aga.model.Context$ContextBuilder$Creator4JacksonDeserializer8cf3272c.createUsingDefault(dev/aga/model/Context$ContextBuilder$Creator4JacksonDeserializer.java)
	at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.vanillaDeserialize(BuilderBasedDeserializer.java:285)
	at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:217)
	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4309)
	at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4245)
	at dev.aga.model.ContextTest.testDeserWithAfterburnerAndUseValueClassLoaderFalse(ContextTest.java:42)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)

austinarbor avatar Mar 11 '21 21:03 austinarbor

Sounds like issue for Java 9+ Module system (JPMS). Not sure what could be done about that, hoping someone else can comment.

cowtowncoder avatar Mar 16 '21 00:03 cowtowncoder

For Lombok users:

I'm experiencing this issue when using @Jacksonized @Builder.

For some reason, if I change the @Builder to @SuperBuilder (I'm not using inheritance, so there is no reason to use @SuperBuilder) it seems to work but with An illegal reflective access operation has occurred warning.

agargaglione avatar Jun 27 '21 15:06 agargaglione

One way out of this could be to extend @JsonDeserialize to support specifying a static builder creation method. In this way, no reflective access to the actual builder class is necessary. Jackson could simply call clazz.getMethod(builderMethod).

janrieke avatar Jan 02 '22 14:01 janrieke

Reflective access is still needed for the builder method (that's what getMethod() is), but that might be easier to open via module definitions.

cowtowncoder avatar Jan 03 '22 00:01 cowtowncoder

Despite the release of Lombok version 1.18.26, the issue mentioned still persists. However, the workaround suggested by @agargaglione still provides a solution

@Jacksonized @SuperBuilder

Gianlo98 avatar May 03 '23 13:05 Gianlo98

Another workaround (that worked for me), is to switch from Afterburner to Blackbird (if you are on Java 11+).

Also Blackbird seems to be the future anyway...

drothmaler avatar Dec 08 '23 15:12 drothmaler