pingidentity / scim2

The UnboundID SCIM 2.0 SDK for Java
184 stars 75 forks source link

PatchRequest causes JsonbException with Spring and Java 17 #218

Closed v0gler closed 7 months ago

v0gler commented 7 months ago

Describe the bug SpringBoot with Apache HttpClient uses jakarta.json.bind.Jsonb for PatchRequest serialization. Since PatchOperation contains private inner classes ,operations property cannot be serialized and causes following exception: jakarta.json.bind.JsonbException: Unable to serialize property 'operations' from com.unboundid.scim2.common.messages.PatchRequest caused by java.lang.IllegalAccessException

To Reproduce Usage of SpringBoot 3 with ApacheHttpClient. Following Code reproduces the issue:

Member member = new Member(); member.setValue("testID"); member.setDisplay("testName"); member.setRef(new URI("testURI")); PatchRequest request = new PatchRequest(PatchOperation.add("members", JsonUtils.valueToNode(member))); Jsonb jsonb = JsonbBuilder.create(); String result = jsonb.toJson(request, PatchRequest.class);

Expected behavior PatchRequest can be serialized properly to be used with SpringBoot.

Additional context Add any other context about the problem here. For example:

Full exception:

   Generating incomplete JSON
   jakarta.json.bind.JsonbException: Unable to serialize property 'operations' from 
   com.unboundid.scim2.common.messages.PatchRequest

at org.eclipse.yasson.internal.serializer.ObjectSerializer.lambda$serialize$0(ObjectSerializer.java:43)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
at org.eclipse.yasson.internal.serializer.ObjectSerializer.serialize(ObjectSerializer.java:38)
at org.eclipse.yasson.internal.serializer.RecursionChecker.serialize(RecursionChecker.java:38)
at org.eclipse.yasson.internal.serializer.KeyWriter.serialize(KeyWriter.java:41)
at org.eclipse.yasson.internal.serializer.NullVisibilitySwitcher.serialize(NullVisibilitySwitcher.java:40)
at org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson.internal.SerializationContextImpl.serializeObject(SerializationContextImpl.java:197)
at org.eclipse.yasson.internal.SerializationContextImpl.marshall(SerializationContextImpl.java:133)
at org.eclipse.yasson.internal.SerializationContextImpl.marshall(SerializationContextImpl.java:159)
at org.eclipse.yasson.internal.JsonBinding.toJson(JsonBinding.java:140)
at com.unboundid.scim2.common.PatchRequestTest.PatchRequestIsSerialisable(PatchRequestTest.java:84)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:664)
at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:227)
at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:957)
at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:200)
at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148)
at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.testng.TestRunner.privateRun(TestRunner.java:848)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:443)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:437)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:397)
at org.testng.SuiteRunner.run(SuiteRunner.java:336)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
at org.testng.TestNG.runSuites(TestNG.java:1114)
at org.testng.TestNG.run(TestNG.java:1082)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Suppressed: jakarta.json.stream.JsonGenerationException: Generating incomplete JSON
    at org.eclipse.parsson.JsonGeneratorImpl.close(JsonGeneratorImpl.java:519)
    at org.eclipse.yasson.internal.JsonBinding.toJson(JsonBinding.java:139)
    ... 28 more

Caused by: jakarta.json.bind.JsonbException: Error accessing getter 'getJsonNode' declared in 'class com.unboundid.scim2.common.messages.PatchOperation$AddOperation' at org.eclipse.yasson.internal.model.PropertyModel.createReadHandle(PropertyModel.java:513) at org.eclipse.yasson.internal.model.PropertyModel.isPropertyReadable(PropertyModel.java:498) at org.eclipse.yasson.internal.ClassParser.getSortedParentProperties(ClassParser.java:328) at org.eclipse.yasson.internal.ClassParser.parseProperties(ClassParser.java:67) at org.eclipse.yasson.internal.MappingContext.lambda$createParseClassModelFunction$1(MappingContext.java:105) at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1740) at org.eclipse.yasson.internal.MappingContext.getOrCreateClassModel(MappingContext.java:77) at org.eclipse.yasson.internal.serializer.SerializationModelCreator.serializerChainInternal(SerializationModelCreator.java:187) at org.eclipse.yasson.internal.serializer.SerializationModelCreator.serializerChainRuntime(SerializationModelCreator.java:123) at org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.lambda$findSerializer$0(ObjectTypeSerializer.java:67) at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) at org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.findSerializer(ObjectTypeSerializer.java:65) at org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serializeValue(ObjectTypeSerializer.java:50) at org.eclipse.yasson.internal.serializer.types.TypeSerializer$ValueSerializer.serialize(TypeSerializer.java:51) at org.eclipse.yasson.internal.serializer.types.TypeSerializer.serialize(TypeSerializer.java:37) at org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serialize(ObjectTypeSerializer.java:31) at org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67) at org.eclipse.yasson.internal.serializer.CollectionSerializer.lambda$serialize$0(CollectionSerializer.java:37) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1092) at org.eclipse.yasson.internal.serializer.CollectionSerializer.serialize(CollectionSerializer.java:37) at org.eclipse.yasson.internal.serializer.KeyWriter.serialize(KeyWriter.java:41) at org.eclipse.yasson.internal.serializer.NullVisibilitySwitcher.serialize(NullVisibilitySwitcher.java:40) at org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67) at org.eclipse.yasson.internal.serializer.ValueGetterSerializer.serialize(ValueGetterSerializer.java:43) at org.eclipse.yasson.internal.serializer.ObjectSerializer.lambda$serialize$0(ObjectSerializer.java:41) ... 38 more Caused by: java.lang.IllegalAccessException: class is not public: com.unboundid.scim2.common.messages.PatchOperation$AddOperation.getJsonNode[Ljava.lang.Object;@1d483de4/invokeSpecial, from public Lookup at java.base/java.lang.invoke.MemberName.makeAccessException(MemberName.java:955) at java.base/java.lang.invoke.MethodHandles$Lookup.checkAccess(MethodHandles.java:3882) at java.base/java.lang.invoke.MethodHandles$Lookup.checkMethod(MethodHandles.java:3822) at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:3967) at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:3960) at java.base/java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:3350) at org.eclipse.yasson.internal.model.PropertyModel.createReadHandle(PropertyModel.java:510) ... 63 more

v0gler commented 7 months ago

Registering clientConfig.register(JacksonFeature.class); in HttpClient fixes this issue.