eclipse-ee4j / eclipse-ee4j/yasson

The example for jakarta.json.bind.annotation.JsonbSubtype is misleading

Open
#660 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
218
Forks
109
Avg merge
1d 5h
Merged PRs (30d)
9

Description

Hello. I use Yasson 3.0.4 with OpenJDK (Temurin) 21.0.5 and Windows 11.

At first, the example for jakarta.json.bind.annotation.JsonbSubtype contains several trivial compile errors that should be fixed even though the purpose isn't to provide a fully working example:
- a comma is missing after the declaration of the first JsonbSubtype annotation
- isDog, isCat and isRat are wrongly declared as String whereas the rest of the source code expects to manipulate booleans

Secondly, the example demonstrates the serialization but not the deserialization.

Thirdly, the deserialization doesn't work as is when fixing the trivial compile errors mentioned earlier except if the interface and the classes are either saved into separate source files or declared static into the same source file:
jakarta.json.bind.JsonbException: Cannot create instance of a class: class Cat, No default constructor found.
at org.eclipse.yasson.internal.deserializer.DefaultObjectInstanceCreator.(DefaultObjectInstanceCreator.java:44)
at org.eclipse.yasson.internal.deserializer.DeserializationModelCreator.createObjectDeserializer(DeserializationModelCreator.java:251)
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.deserializer.InheritanceInstanceCreator.deserialize(InheritanceInstanceCreator.java:71)
at org.eclipse.yasson.internal.deserializer.InheritanceInstanceCreator.deserialize(InheritanceInstanceCreator.java:31)
at org.eclipse.yasson.internal.deserializer.PositionChecker.deserialize(PositionChecker.java:85)
at org.eclipse.yasson.internal.deserializer.PositionChecker.deserialize(PositionChecker.java:34)
at org.eclipse.yasson.internal.deserializer.NullCheckDeserializer.deserialize(NullCheckDeserializer.java:46)
at org.eclipse.yasson.internal.deserializer.NullCheckDeserializer.deserialize(NullCheckDeserializer.java:26)
at org.eclipse.yasson.internal.DeserializationContextImpl.deserializeItem(DeserializationContextImpl.java:138)
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)

Please find below the minimal changes I suggest for the example:

```
// Example
// Animal.java
@JsonbTypeInfo({
@JsonbSubtype(alias = "dog", type = Dog.class),
@JsonbSubtype(alias = "cat", type = Cat.class)
})
interface Animal {}

// Dog.java
class Dog implements Animal {
public boolean isDog = true;
}
// Cat.java
class Cat implements Animal {
public boolean isCat = true;
}
// Rat.java
class Rat implements Animal {
public boolean isRat = true;
}

jsonb.toJson(new Dog());// {"@type":"dog","isDog":true}
jsonb.toJson(new Cat());// {"@type":"cat","isCat":true}
jsonb.toJson(new Rat());// {"isRat":true}
jsonb.fromJson("{\"@type\":\"cat\",\"isCat\":true}", Animal.class);// Cat@...
```

Please find below my fully working example:

```
public class Main {
@JsonbTypeInfo({
@JsonbSubtype(alias = "dog", type = Dog.class),
@JsonbSubtype(alias = "cat", type = Cat.class)
})
public static interface Animal {
}

public static final class Dog implements Animal {

public boolean isDog = true;
}

public static final class Cat implements Animal {

public boolean isCat = true;
}

public static final class Rat implements Animal {

public boolean isRat = true;
}

public static void main(final String[] args) throws Exception {
try (final Jsonb jsonb = JsonbBuilder.create()) {
System.out.println(jsonb.toJson(new Dog()));
System.out.println(jsonb.toJson(new Cat()));
System.out.println(jsonb.toJson(new Rat()));
System.out.println(jsonb.fromJson("{\"@type\":\"cat\",\"isCat\":true}", Animal.class));
}
}
}
```

Feel free to move this issue upstream if it makes sense for you.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.