You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@johnzon.apache.org by "Romain Manni-Bucau (Jira)" <ji...@apache.org> on 2020/03/27 09:06:00 UTC

[jira] [Commented] (JOHNZON-309) Yasson compliant Adapter fails with Johnzon

    [ https://issues.apache.org/jira/browse/JOHNZON-309?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17068445#comment-17068445 ] 

Romain Manni-Bucau commented on JOHNZON-309:
--------------------------------------------

Hmm, this is an interesting case because adapters are not well defined in the specification (for various reasons, one being it is not that trivial to handle this mapping which can imply a lot of rules).

Johnzon does not apply adapters on primitives, in other words, if you wrap your adapter in an object it will work.

I'll have a look if we can make something better without impacting too much performances but issue with Path is you never give a Path instance but an UnixPath or WindowsPath instance and there spec is unclear too if subclass should match or not since it has cons too.

> Yasson compliant Adapter fails with Johnzon
> -------------------------------------------
>
>                 Key: JOHNZON-309
>                 URL: https://issues.apache.org/jira/browse/JOHNZON-309
>             Project: Johnzon
>          Issue Type: Bug
>          Components: JSON-B
>    Affects Versions: 1.2.3
>         Environment: Operating System: Ubuntu 18.04.04
> Java: 11.0.4
>            Reporter: James Baker
>            Priority: Major
>
> I have written a simple adapter to allow the serialization and deserialization of Java Path objects. The adapter works fine using Yasson (which claims to be a reference implementation), but both serialization and deserialization fail in Johnzon.
> Serialization results in a StackOverflowError:
> {noformat}
> java.lang.StackOverflowError
>  at org.apache.johnzon.core.JsonGeneratorImpl.currentState(JsonGeneratorImpl.java:676)
>  at org.apache.johnzon.core.JsonGeneratorImpl.prepareValue(JsonGeneratorImpl.java:641)
>  at org.apache.johnzon.core.JsonGeneratorImpl.writeStartArray(JsonGeneratorImpl.java:161)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteIterable(MappingGeneratorImpl.java:682)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteObject(MappingGeneratorImpl.java:156)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.writeItem(MappingGeneratorImpl.java:672)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteIterable(MappingGeneratorImpl.java:691)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteObject(MappingGeneratorImpl.java:156)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.writeItem(MappingGeneratorImpl.java:672)
>  at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteIterable(MappingGeneratorImpl.java:691)
> ...{noformat}
> Deserialization results in an IllegalArgumentException:
>  
> {noformat}
> java.lang.IllegalArgumentException: Unsupported "/example/file.txt" for type interface java.nio.file.Path
> at org.apache.johnzon.mapper.MappingParserImpl.readObject(MappingParserImpl.java:238)
>  at org.apache.johnzon.mapper.MappingParserImpl.readObject(MappingParserImpl.java:139)
>  at org.apache.johnzon.mapper.MappingParserImpl.readObject(MappingParserImpl.java:131)
>  at org.apache.johnzon.mapper.Mapper.mapObject(Mapper.java:371)
>  at org.apache.johnzon.mapper.Mapper.readObject(Mapper.java:297)
>  at org.apache.johnzon.mapper.Mapper.readObject(Mapper.java:292)
>  at org.apache.johnzon.jsonb.JohnzonJsonb.fromJson(JohnzonJsonb.java:77)
>  at org.example.json.serialization.PathAdapterTest.testDeserialize(PathAdapterTest.java:25)
>  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)
>  at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
>  at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
>  at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
>  at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
>  at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
>  at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
>  at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
>  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
>  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
>  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
>  at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
>  at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
>  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
>  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
>  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
>  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
>  at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
>  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
>  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
>  at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
>  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
>  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
>  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
>  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
>  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
>  at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
>  at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
>  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
>  at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
>  at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
>  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
>  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
>  at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
>  at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
>  at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
>  at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
> {noformat}
>  
> The code is as follows:
> *PathAdapter.java*
> {code:java}
> package org.example.json.serialization;
> import javax.json.Json;
> import javax.json.JsonString;
> import javax.json.bind.adapter.JsonbAdapter;
> import java.nio.file.Path;
> public class PathAdapter implements JsonbAdapter<Path, JsonString> {
>   @Override
>   public JsonString adaptToJson(Path path) {
>     return Json.createValue(path.toString());
>   }
>   @Override
>   public Path adaptFromJson(JsonString jsonString) {
>     return Path.of(jsonString.getString());
>   }
> }
> {code}
> *PathAdapterTest.java*
> {code:java}
> package org.example.json.serialization;
> import org.junit.jupiter.api.Test;
> import javax.json.bind.Jsonb;
> import javax.json.bind.JsonbBuilder;
> import javax.json.bind.JsonbConfig;
> import java.nio.file.Path;
> import static org.junit.jupiter.api.Assertions.assertEquals;
> public class PathAdapterTest {
>   private static final String PATH = "/example/file.txt";
>   private static final Path P_PATH = Path.of(PATH);
>   private static final Jsonb JSONB = JsonbBuilder.create(new JsonbConfig().withAdapters(new PathAdapter()));
>   @Test
>   public void testSerialize(){
>     assertEquals("\"" + PATH + "\"", JSONB.toJson(P_PATH));
>   }
>   @Test
>   public void testDeserialize(){
>     assertEquals(P_PATH, JSONB.fromJson("\"" + PATH + "\"", Path.class));
>   }
> }
> {code}
> *pom.xml*
> {code:java}
> <?xml version="1.0" encoding="UTF-8"?>
> <project xmlns="http://maven.apache.org/POM/4.0.0"
>          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>   <modelVersion>4.0.0</modelVersion>
>   <groupId>org.example</groupId>
>   <artifactId>jsonb-adapter-test</artifactId>
>   <version>1.0-SNAPSHOT</version>
>   <properties>
>     <maven.compiler.source>11</maven.compiler.source>
>     <maven.compiler.target>11</maven.compiler.target>
>   </properties>
>   <dependencies>
>     <dependency>
>       <groupId>javax.json</groupId>
>       <artifactId>javax.json-api</artifactId>
>       <version>1.1.4</version>
>     </dependency>
>     <dependency>
>       <groupId>javax.json.bind</groupId>
>       <artifactId>javax.json.bind-api</artifactId>
>       <version>1.0</version>
>     </dependency>
>     <dependency>
>       <groupId>org.apache.johnzon</groupId>
>       <artifactId>johnzon-jsonb</artifactId>
>       <version>1.2.3</version>
>     </dependency>
>     <!--<dependency>
>       <groupId>org.eclipse</groupId>
>       <artifactId>yasson</artifactId>
>       <version>1.0.6</version>
>     </dependency>-->
>     <dependency>
>       <groupId>org.junit.jupiter</groupId>
>       <artifactId>junit-jupiter-api</artifactId>
>       <version>5.6.1</version>
>       <scope>test</scope>
>     </dependency>
>   </dependencies>
> </project>
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)