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

JSON deserialization issue of selfservice API in Java SDK #154

Closed
4 of 6 tasks
ghost opened this issue Mar 1, 2022 · 10 comments
Closed
4 of 6 tasks

JSON deserialization issue of selfservice API in Java SDK #154

ghost opened this issue Mar 1, 2022 · 10 comments
Labels
bug Something is not working.

Comments

@ghost
Copy link

ghost commented Mar 1, 2022

Preflight checklist

Describe the bug

We have just started evaluating Ory Kratos and Ory Cloud as a cloud service for us.
I´m currently working with Ory Kratos Java SDK, to get connected via API to Ory Cloud v0.8.3-alpha.1.pre.0.0.20220221123934-668f6b246db1 and got into a JSON deserialization error. I´m trying to initializeSelfServiceLoginFlowWithoutBrowser() of V0alpha2API, where I get a java.lang.IllegalArgumentException: field sh.ory.kratos.model.UiNode.attributes has type sh.ory.kratos.model.UiNodeAttributes, got sh.ory.kratos.model.UiNodeInputAttributes. It looks pretty close to #75 .
#75 was solved with Ory Kratos v0.7. I have checked several versions of Ory Kratos v0.7 Java SDK, which worked as expected, but with v0.8.0-alpha2 and newer I see the IllegalArgumentException again.

Reproducing the bug

Kratos Java SDK

  1. init API client: ApiClient apiClient = Configuration.getDefaultApiClient();
  2. set path, e.g.: apiClient.setBasePath("https://playground.projects.oryapis.com/api/kratos/public");
  3. init V0alpha2API: V0alpha2Api oryApiAlpha2 = new V0alpha2Api(apiClient);
  4. init self service login flow: oryApiAlpha2.initializeSelfServiceLoginFlowWithoutBrowser(null, null, null);

Relevant log output

W/System.err: java.lang.IllegalArgumentException: field sh.ory.kratos.model.UiNode.attributes has type sh.ory.kratos.model.UiNodeAttributes, got sh.ory.kratos.model.UiNodeInputAttributes
W/System.err:     at java.lang.reflect.Field.set(Native Method)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:133)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
W/System.err:     at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
W/System.err:     at com.google.gson.Gson.fromJson(Gson.java:932)
W/System.err:     at com.google.gson.Gson.fromJson(Gson.java:897)
W/System.err:     at com.google.gson.Gson.fromJson(Gson.java:846)
W/System.err:     at sh.ory.kratos.JSON.deserialize(JSON.java:232)
W/System.err:     at sh.ory.kratos.ApiClient.deserialize(ApiClient.java:795)
W/System.err:     at sh.ory.kratos.ApiClient.handleResponse(ApiClient.java:1001)
W/System.err:     at sh.ory.kratos.ApiClient.execute(ApiClient.java:925)
W/System.err:     at sh.ory.kratos.api.V0alpha2Api.initializeSelfServiceLoginFlowWithoutBrowserWithHttpInfo(V0alpha2Api.java:2349)
W/System.err:     at sh.ory.kratos.api.V0alpha2Api.initializeSelfServiceLoginFlowWithoutBrowser(V0alpha2Api.java:2326)

Relevant configuration

No response

Version

v0.8.0-alpha2 and newer

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

No response

Additional Context

No response

@ghost ghost added the bug Something is not working. label Mar 1, 2022
@ghost
Copy link
Author

ghost commented Mar 3, 2022

It seems to be related with the "discriminator" updates in ".schema/openapi/patches/schema.yaml" of commit 59e808e8dc6339da59bbe08ebbcf7b840e3fdd50 (Ory Kratos repo).
If I remove the following:

.registerTypeSelector(UiNodeAttributes.class, new TypeSelector<UiNodeAttributes>() {
                    @Override
                    public Class<? extends UiNodeAttributes> getClassForElement(JsonElement readElement) {
                        Map<String, Class> classByDiscriminatorValue = new HashMap<String, Class>();
                        classByDiscriminatorValue.put("anchor", UiNodeAnchorAttributes.class);
                        classByDiscriminatorValue.put("image", UiNodeImageAttributes.class);
                        classByDiscriminatorValue.put("input", UiNodeInputAttributes.class);
                        classByDiscriminatorValue.put("script", UiNodeScriptAttributes.class);
                        classByDiscriminatorValue.put("text", UiNodeTextAttributes.class);
                        classByDiscriminatorValue.put("uiNodeAnchorAttributes", UiNodeAnchorAttributes.class);
                        classByDiscriminatorValue.put("uiNodeImageAttributes", UiNodeImageAttributes.class);
                        classByDiscriminatorValue.put("uiNodeInputAttributes", UiNodeInputAttributes.class);
                        classByDiscriminatorValue.put("uiNodeScriptAttributes", UiNodeScriptAttributes.class);
                        classByDiscriminatorValue.put("uiNodeTextAttributes", UiNodeTextAttributes.class);
                        classByDiscriminatorValue.put("uiNodeAttributes", UiNodeAttributes.class);
                        return getClassByDiscriminator(classByDiscriminatorValue,
                                getDiscriminatorValue(readElement, "node_type"));
                    }
          })

generated java code in "kratos-client-java/src/main/java/sh/ory/kratos/JSON.java" below:

public static GsonBuilder createGson() {
        GsonFireBuilder fireBuilder = new GsonFireBuilder()

and compile Java SDK with Maven mvn clean package, it is working.

With this workaround it seems that it is working for my current SDK evaluation purpose, but wouldn´t be useful for a release.

@ghost
Copy link
Author

ghost commented Mar 29, 2022

I changed library to jersey2. With this library it is working without the discriminator problem

@Empyreans
Copy link

Could you please elaborate how exactly you fixed the problem? You switched the Json library?

@aeneasr
Copy link
Member

aeneasr commented Mar 30, 2022

Which one is the recommended generator for Java? We can also update it if that generator is less buggy

@ghost
Copy link
Author

ghost commented Mar 30, 2022

The underlying openapi-generator supports several http libraries for java (see "library" at openapi-generator.tech). Default is "okhttp-gson" which causes the discriminator problems in my case.
In "sdk" section of Ory Kratos Makefile (Ory Kratos root directory), there is a call of "openapi-generator-cli". I added the jersey2 library.
It looks now as following (I added the "--additional-properties..." line):

npm run openapi-generator-cli -- generate -i "spec/api.json" \
    -g java \
    -o "internal/httpclient" \
    --additional-properties=library=jersey2 \

I hope this helps to unserstand what I did.

Jersey2 was working in my case. I´m not sure if it makes sense as a general solution

@aeneasr
Copy link
Member

aeneasr commented Apr 9, 2022

Thank you for the reply! Switching generators is a possibility. Unfortunately I have very little experience with Java and don’t really know what libraries are en vogue and which ones aren’t. It also depends a bit on the support of the generator in the openapi tooling. @piotrmsc do you have experience with these libs in Java?

@notmeta
Copy link

notmeta commented Apr 23, 2022

Getting this too, noticed it only happens with null/"aal1" as aal parameters in the initialisation function, otherwise there are other errors (e.g. bad request for invalid session token).

@dstockhammer
Copy link

I think jackson would be a safer choice for the serializer. Not entirely sure why the generator uses okhttp-gson as default, but I'd assume it's for backwards-compatibility since changing any of the underlying libraries would be a breaking change.

For the HTTP client on the other hand I don't think there's a clear winner. native might be a good alternative, but that would require Java 11 which is probably not acceptable. Since the default is okhttp the safest choice is probably to leave it at that 🤷

So if you'd be willing to change the serializationLibrary to jackson I think that would be an improvement for most use cases. Though it's a breaking change that can cause problems depending on how the library is used and what other libraries there are in the project.

@aeneasr
Copy link
Member

aeneasr commented Dec 6, 2022

Can anyone confirm that this is still an issue?

@ghost
Copy link
Author

ghost commented Dec 22, 2022

No response yet and I´m currently working on other projects. I will close this issue.

@ghost ghost closed this as completed Dec 22, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working.
Projects
None yet
Development

No branches or pull requests

6 participants