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

Issue with @JsonbCreator constructor with Generic Type in Yasson 3.0.0 and higher #599

Open
mskacelik opened this issue May 5, 2023 · 4 comments
Labels
bug Something isn't working right

Comments

@mskacelik
Copy link

mskacelik commented May 5, 2023

There seems to be a bug in Yasson version 3.0.0 and higher that affects the @JsonbCreator constructor when it has a Generic Type parameter. This issue is not present in Yasson version 2.0.4.

Stack trace from the reproducer (version 3.0.0 and higher):

Exception in thread "main" jakarta.json.bind.JsonbException: Error resolving runtime type for type: T
	at org.eclipse.yasson.internal.ReflectionUtils.lambda$getRawType$0(ReflectionUtils.java:92)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at org.eclipse.yasson.internal.ReflectionUtils.getRawType(ReflectionUtils.java:92)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createObjectDeserializer(DeserializationModelCreator.java:236)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChainInternal(DeserializationModelCreator.java:193)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChain(DeserializationModelCreator.java:135)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createNewChain(DeserializationModelCreator.java:488)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.typeProcessor(DeserializationModelCreator.java:477)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.typeProcessor(DeserializationModelCreator.java:430)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createCollectionDeserializer(DeserializationModelCreator.java:273)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChainInternal(DeserializationModelCreator.java:183)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChain(DeserializationModelCreator.java:135)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createNewChain(DeserializationModelCreator.java:488)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.typeProcessor(DeserializationModelCreator.java:477)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.typeProcessor(DeserializationModelCreator.java:430)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createObjectDeserializer(DeserializationModelCreator.java:227)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChainInternal(DeserializationModelCreator.java:193)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChain(DeserializationModelCreator.java:135)
	at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChain(DeserializationModelCreator.java:123)
	at org.eclipse.yasson.internal.DeserializationContextImpl.deserializeItem(DeserializationContextImpl.java:137)
	at org.eclipse.yasson.internal.DeserializationContextImpl.deserialize(DeserializationContextImpl.java:127)
	at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:55)
	at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:62)
	at Reproducer.main(Reproducer.java:27)

Reproducer using JBang:

///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS org.eclipse:yasson:3.0.3


import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbConfig;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.annotation.JsonbCreator;
import java.util.List;


public class Reproducer {

    public static void main(String... args) {
        Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
                .withFormatting(true)
                .withNullValues(true));
        String jsonString = "{\n" +
                "    \"id\": 0,\n" +
                "    \"multiLangRecords\": [{\n" +
                "      \"lang\": \"\",\n" +
                "      \"record\": {\n" +
                "        \"description\": \"\"\n" +
                "      }\n" +
                "    }]  \n" +
                "  }";
        System.out.println(jsonb.fromJson(jsonString, InsertTechnicalLocationInputJ.class));
        // EXPECTED: InsertTechnicalLocationInputJ[id=0, multiLangRecords=[InsertLangEntryGQLJ[lang=, record=InsertTechnicalLocationRecordGQLJ[description=]]]]
    }

    public record InsertTechnicalLocationInputJ(String id,
                                                List<InsertLangEntryGQLJ<InsertTechnicalLocationRecordGQLJ>> multiLangRecords) {

        @JsonbCreator
        public InsertTechnicalLocationInputJ {
        }
    }

    public record InsertTechnicalLocationRecordGQLJ(String description) {

        @JsonbCreator
        public InsertTechnicalLocationRecordGQLJ {
        }
    }

    public record InsertLangEntryGQLJ<T>(String lang, T record) {
        @JsonbCreator
        public InsertLangEntryGQLJ {
        }
    }

}

Switching yasson's version (line starting //DEPS) from 3.0.3 to 2.0.4 resolves the issue.

JBang documentation and how to download it: https://www.jbang.dev/

@Degubi
Copy link
Contributor

Degubi commented Jul 10, 2023

The first commit where this error gets thrown is b74033d
Not sure what caused this because the diff is huge

@edgarvonk
Copy link

It seems we are facing the same issue using Yasson 3.0.2 (which ships with WildFly 30):

jakarta.ws.rs.ProcessingException: RESTEASY008200: JSON Binding deserialization error: jakarta.json.bind.JsonbException: Error resolving runtime type for type: T
	at org.jboss.resteasy.resteasy-json-binding-provider@6.2.5.Final//org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider.readFrom(JsonBindingProvider.java:78
	
[..]
Caused by: jakarta.json.bind.JsonbException: Error resolving runtime type for type: T
	at org.eclipse.yasson//org.eclipse.yasson.internal.ReflectionUtils.lambda$getRawType$0(ReflectionUtils.java:92)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at org.eclipse.yasson//org.eclipse.yasson.internal.ReflectionUtils.getRawType(ReflectionUtils.java:92)
	at org.eclipse.yasson//org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createObjectDeserializer(DeserializationModelCreator.java:236)
	at org.eclipse.yasson//org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChainInternal(DeserializationModelCreator.java:193)
	at org.eclipse.yasson//org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChain(DeserializationModelCreator.java:135)
	at org.eclipse.yasson//org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.deserializerChain(DeserializationModelCreator.java:123)
	at org.eclipse.yasson//org.eclipse.yasson.internal.DeserializationContextImpl.deserializeItem(DeserializationContextImpl.java:137)
	at org.eclipse.yasson//org.eclipse.yasson.internal.DeserializationContextImpl.deserialize(DeserializationContextImpl.java:127)
	at org.eclipse.yasson//org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:55)
	at org.eclipse.yasson//org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:95)
	at org.jboss.resteasy.resteasy-json-binding-provider@6.2.5.Final//org.jboss.resteasy.plugins.providers.jsonb.ManagedJsonb.fromJson(ManagedJsonb.java:73)
	at org.jboss.resteasy.resteasy-json-binding-provider@6.2.5.Final//org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider.readFrom(JsonBindingProvider.java:71)	

In our case the Java data class in question which Yasson is trying to deserialize is:

public class RuleResponse<T> {

    private final T result;

    @JsonbCreator
    public RuleResponse(@JsonbProperty("result") final T result) {
        this.result = result;
    }

    public T getResult() {
        return result;
    }
}

Is there a workaround for this issue? We cannot just downgrade Yasson because Yasson 3 is used internally by WildFly a lot as well it seems.

@mskacelik
Copy link
Author

@edgarvonk Possible workaround was brought up here: smallrye/smallrye-graphql#1819 (comment)

@edgarvonk
Copy link

Thanks @mskacelik ! It seems to do the trick indeed. A rather cumbersome workaround for us however since our code base is large with quite a huge number of Java value classes that do not implement an interface nor extend from an abstract class which are used as generic types in JSON deserialisation..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working right
Projects
None yet
Development

No branches or pull requests

3 participants