-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Labels
3.0Issue planned for initial 3.0 releaseIssue planned for initial 3.0 release
Milestone
Description
After migrating from Jackson 2.x to Jackson 3.x, calling AnnotatedMember.annotations() throws a NullPointerException when the member has no annotations. In 2.x it was possible to fetch the annotations via AnnotatedMember.getAllAnnotations(), but this method does not exist anymore in Jackson 3.x. This breaks my custom logic that filters properties by annotations during serialization.
Edit: I can't use AnnotatedMember.getAnnotation() (although it would be possible in the simplified example below) because I don't always know the exact annotation class. Instead, I need to iterate over all annotations and, for example, search for meta annotations.
How to Reproduce
Execute the main method of the following class:
package com.example;
import tools.jackson.databind.BeanDescription;
import tools.jackson.databind.SerializationConfig;
import tools.jackson.databind.introspect.AnnotatedMember;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.module.SimpleModule;
import tools.jackson.databind.ser.BeanPropertyWriter;
import tools.jackson.databind.ser.ValueSerializerModifier;
import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
public class MyClass {
public static void main(String[] args) {
var mapper = JsonMapper.builder().addModule(new HiddenFieldModule()).build();
var user = new User("John", "123456");
var userJson = mapper.writeValueAsString(user);
System.out.println(userJson);
}
// HiddenFieldModule should prevent the output of the password field.
record User(String name, @Hidden String password) {}
@Retention(RUNTIME)
@interface Hidden {}
static class HiddenFieldModule extends SimpleModule {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addSerializerModifier(new HiddenFieldRemover());
}
}
static class HiddenFieldRemover extends ValueSerializerModifier {
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription.Supplier beanDesc, List<BeanPropertyWriter> beanProperties) {
return beanProperties.stream()
.filter(writer -> !isHidden(writer.getMember()))
.collect(Collectors.toCollection(ArrayList::new));
}
private boolean isHidden(AnnotatedMember member) {
if (member.annotations() == null) {
return false;
}
return member
.annotations()
.anyMatch(annotation -> annotation.annotationType().equals(Hidden.class));
}
}
}Expected Output
{"name":"John"}Actual Output
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "tools.jackson.databind.introspect.AnnotationMap.values()" because "this._annotations" is null
at tools.jackson.databind.introspect.AnnotatedMember.annotations(AnnotatedMember.java:83)
at com.example.MyClass$HiddenFieldRemover.isHidden(MyClass.java:49)Metadata
Metadata
Assignees
Labels
3.0Issue planned for initial 3.0 releaseIssue planned for initial 3.0 release