-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Labels
RecordIssue related to JDK17 java.lang.Record supportIssue related to JDK17 java.lang.Record support
Milestone
Description
Describe the bug
With v 2.15.x I run into com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)
. The code works with 2.14.2
To Reproduce
Run the unit test below, see comments in the code
package org.acme.json.error;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
class SerializationTest {
private ObjectMapper objectMapper;
@BeforeEach
void setUp() {
objectMapper = new ObjectMapper();
}
@Test
public void greeting() throws JsonProcessingException {
var beanWithRecursion = new Recursion();
beanWithRecursion.add(beanWithRecursion);
var gr = new GreetingWithTransientRecursion("hello", beanWithRecursion);
var json = objectMapper.writer().writeValueAsString(gr);
System.out.println(json);
}
@Test
public void hello() throws JsonProcessingException {
var beanWithRecursion = new Recursion();
beanWithRecursion.add(beanWithRecursion);
var hello = new HelloWithoutTransientRecursion("hello", beanWithRecursion);
var json = objectMapper.writer().writeValueAsString(hello);
System.out.println(json);
}
@Test
public void hellorecord() throws JsonProcessingException {
var beanWithRecursion = new Recursion();
beanWithRecursion.add(beanWithRecursion);
var hello = new HelloRecord("hello", beanWithRecursion);
var json = objectMapper.writer().writeValueAsString(hello);
System.out.println(json);
}
//works fine as the class but not if converted to record
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class HelloWithoutTransientRecursion implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private final String text;
@JsonIgnore
private final Recursion hidden;
public HelloWithoutTransientRecursion(String text, Recursion hidden) {
this.text = text;
this.hidden = hidden;
}
public String getText() {
return text;
}
public Recursion getHidden() {
return hidden;
}
@Override
public String toString() {
return "GreetingWithTransientRecursion{" +
"text='" + text + '\'' +
", hidden='" + hidden + '\'' +
'}';
}
}
/**
* Infinite recursion (StackOverflowError)
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public record HelloRecord(String text, @JsonIgnore Recursion hidden) {
/**
* when the method is not overriden it works
*/
@Override
public Recursion hidden() {
return hidden;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static final class GreetingWithTransientRecursion implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String text;
@JsonIgnore
private transient Recursion hidden; //transient keyword causes Infinite recursion (StackOverflowError)
public GreetingWithTransientRecursion(String text, Recursion hidden) {
this.text = text;
this.hidden = hidden;
}
public void setText(String text) {
this.text = text;
}
public void setHidden(Recursion hidden) {
this.hidden = hidden;
}
public String getText() {
return text;
}
public Recursion getHidden() {
return hidden;
}
}
public static class Recursion {
private final List<Recursion> all = new ArrayList<>();
void add(Recursion recursion) {
all.add(recursion);
}
public List<Recursion> getAll() {
return all;
}
}
}
Metadata
Metadata
Assignees
Labels
RecordIssue related to JDK17 java.lang.Record supportIssue related to JDK17 java.lang.Record support