-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
to-evaluateIssue that has been received but not yet evaluatedIssue that has been received but not yet evaluated
Description
Search before asking
- I searched in the issues and found nothing similar.
Describe the bug
I opened a Spring Boot issue, but it seems the issue is Jackson related. See spring-projects/spring-boot#46994 (comment) for the full details and a reproducer.
Version Information
2.19.2
Reproduction
package com.example.jsontesterbug;
import static org.assertj.core.api.Assertions.assertThat;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
class MessageWrapperTest {
private MessageWrapper<?> wildcardWrapper;
private MessageWrapper<EmailSettings> specificWrapper;
private ObjectMapper objectMapper = new ObjectMapper();
@Test
void wildcardWrapper() throws NoSuchFieldException, SecurityException, JsonProcessingException {
serializeWithTypeFromField("wildcardWrapper");
}
@Test
void specificWrapper() throws NoSuchFieldException, SecurityException, JsonProcessingException {
serializeWithTypeFromField("specificWrapper");
}
private void serializeWithTypeFromField(String field) throws NoSuchFieldException, SecurityException, JsonProcessingException {
MessageWrapper<EmailSettings> wrapper = new MessageWrapper<>(new EmailSettings("[email protected]"),
"Sample Message");
Type genericType = MessageWrapperTest.class.getDeclaredField(field).getGenericType();
TypeVariable<?>[] typeParameters = ((Class<?>)((ParameterizedType)genericType).getRawType()).getTypeParameters();
Type[] bounds = typeParameters[0].getBounds();
System.out.println(field);
System.out.println(" Generic type: " + genericType);
System.out.println(" Bounds: " + Arrays.toString(bounds));
JavaType jacksonType = this.objectMapper.constructType(genericType);
System.out.println(" Jackson type: " + jacksonType);
String json = this.objectMapper.writerFor(jacksonType).writeValueAsString(wrapper);
System.out.println(" JSON: " + json);
assertThat(json).contains("\"type\":\"EMAIL\"");
assertThat(json).contains("\"email\":\"[email protected]\"");
}
}
Running this gives this output:
wildcardWrapper
Generic type: com.example.jsontesterbug.MessageWrapper<?>
Bounds: [interface com.example.jsontesterbug.Settings]
Jackson type: [simple type, class com.example.jsontesterbug.MessageWrapper<java.lang.Object>]
JSON: {"settings":{"email":"[email protected]"},"message":"Sample Message"}
specificWrapper
Generic type: com.example.jsontesterbug.MessageWrapper<com.example.jsontesterbug.EmailSettings>
Bounds: [interface com.example.jsontesterbug.Settings]
Jackson type: [simple type, class com.example.jsontesterbug.MessageWrapper<com.example.jsontesterbug.EmailSettings>]
JSON: {"settings":{"type":"EMAIL","email":"[email protected]"},"message":"Sample Message"}
Expected behavior
The JSON output should be the same in both cases.
Additional context
No response
Metadata
Metadata
Assignees
Labels
to-evaluateIssue that has been received but not yet evaluatedIssue that has been received but not yet evaluated