Skip to content

Commit 46dd589

Browse files
mariofuscogsmet
authored andcommitted
Allow to register generated Jackson serializers at any moment during quarkus strartup
(cherry picked from commit e5caa13)
1 parent 1bec102 commit 46dd589

File tree

2 files changed

+29
-51
lines changed

2 files changed

+29
-51
lines changed

extensions/resteasy-reactive/rest-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/ResteasyReactiveServerJacksonRecorder.java

+3-15
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
import java.lang.reflect.Type;
44
import java.util.HashMap;
5-
import java.util.HashSet;
65
import java.util.Map;
7-
import java.util.Set;
86
import java.util.concurrent.ConcurrentHashMap;
97
import java.util.function.BiConsumer;
108
import java.util.function.BiFunction;
@@ -18,6 +16,7 @@
1816

1917
import io.quarkus.arc.Arc;
2018
import io.quarkus.resteasy.reactive.jackson.runtime.security.RolesAllowedConfigExpStorage;
19+
import io.quarkus.resteasy.reactive.jackson.runtime.serialisers.GeneratedSerializersRegister;
2120
import io.quarkus.runtime.RuntimeValue;
2221
import io.quarkus.runtime.ShutdownContext;
2322
import io.quarkus.runtime.annotations.Recorder;
@@ -29,9 +28,6 @@ public class ResteasyReactiveServerJacksonRecorder {
2928
private static final Map<String, Class<?>> customSerializationMap = new HashMap<>();
3029
private static final Map<String, Class<?>> customDeserializationMap = new HashMap<>();
3130

32-
private static final Set<Class<? extends StdSerializer>> generatedSerializers = new HashSet<>();
33-
private static final Set<Class<? extends StdDeserializer>> generatedDeserializers = new HashSet<>();
34-
3531
/* STATIC INIT */
3632
public RuntimeValue<Map<String, Supplier<String[]>>> createConfigExpToAllowedRoles() {
3733
return new RuntimeValue<>(new ConcurrentHashMap<>());
@@ -84,11 +80,11 @@ public void recordCustomDeserialization(String target, String className) {
8480
}
8581

8682
public void recordGeneratedSerializer(String className) {
87-
generatedSerializers.add((Class<? extends StdSerializer>) loadClass(className));
83+
GeneratedSerializersRegister.addSerializer((Class<? extends StdSerializer>) loadClass(className));
8884
}
8985

9086
public void recordGeneratedDeserializer(String className) {
91-
generatedDeserializers.add((Class<? extends StdDeserializer>) loadClass(className));
87+
GeneratedSerializersRegister.addDeserializer((Class<? extends StdDeserializer>) loadClass(className));
9288
}
9389

9490
public void configureShutdown(ShutdownContext shutdownContext) {
@@ -131,14 +127,6 @@ public static Class<? extends BiFunction<ObjectMapper, Type, ObjectReader>> cust
131127
return (Class<? extends BiFunction<ObjectMapper, Type, ObjectReader>>) customDeserializationMap.get(clazz.getName());
132128
}
133129

134-
public static Set<Class<? extends StdSerializer>> getGeneratedSerializers() {
135-
return generatedSerializers;
136-
}
137-
138-
public static Set<Class<? extends StdDeserializer>> getGeneratedDeserializers() {
139-
return generatedDeserializers;
140-
}
141-
142130
private Class<?> loadClass(String className) {
143131
try {
144132
return Thread.currentThread().getContextClassLoader().loadClass(className);

extensions/resteasy-reactive/rest-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/GeneratedSerializersRegister.java

+26-36
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.fasterxml.jackson.databind.BeanDescription;
1010
import com.fasterxml.jackson.databind.JavaType;
1111
import com.fasterxml.jackson.databind.JsonSerializer;
12-
import com.fasterxml.jackson.databind.Module;
1312
import com.fasterxml.jackson.databind.ObjectMapper;
1413
import com.fasterxml.jackson.databind.SerializationConfig;
1514
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
@@ -18,51 +17,42 @@
1817
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
1918

2019
import io.quarkus.jackson.ObjectMapperCustomizer;
21-
import io.quarkus.resteasy.reactive.jackson.runtime.ResteasyReactiveServerJacksonRecorder;
2220

2321
@Singleton
2422
public class GeneratedSerializersRegister implements ObjectMapperCustomizer {
2523

24+
private static final SimpleModule mappingModule = new SimpleModule();
25+
private static final ExactSerializers serializers = new ExactSerializers();
26+
27+
static {
28+
// Use a custom SimpleSerializers to use a json serializer only if it has been generated for that
29+
// exact class and not one of its sublclasses. This is already the default behaviour for deserializers.
30+
mappingModule.setSerializers(serializers);
31+
}
32+
2633
@Override
2734
public void customize(ObjectMapper objectMapper) {
28-
objectMapper.registerModule(MappingModuleHolder.mappingModule);
35+
objectMapper.registerModule(mappingModule);
2936
}
3037

31-
static class MappingModuleHolder {
32-
static final Module mappingModule = createMappingModule();
33-
34-
private static Module createMappingModule() {
35-
SimpleModule module = new SimpleModule();
36-
// Use a custom SimpleSerializers to use a json serializer only if it has been generated for that
37-
// exact class and not one of its sublclasses. This is already the default behaviour for deserializers.
38-
ExactSerializers serializers = new ExactSerializers();
39-
40-
for (Class<? extends StdSerializer> serClass : ResteasyReactiveServerJacksonRecorder.getGeneratedSerializers()) {
41-
try {
42-
StdSerializer serializer = serClass.getConstructor().newInstance();
43-
serializers.addExactSerializer(serializer.handledType(), serializer);
44-
} catch (InstantiationException | IllegalAccessException | InvocationTargetException
45-
| NoSuchMethodException e) {
46-
throw new RuntimeException(e);
47-
}
48-
}
49-
50-
module.setSerializers(serializers);
51-
52-
for (Class<? extends StdDeserializer> deserClass : ResteasyReactiveServerJacksonRecorder
53-
.getGeneratedDeserializers()) {
54-
try {
55-
StdDeserializer deserializer = deserClass.getConstructor().newInstance();
56-
module.addDeserializer(deserializer.handledType(), deserializer);
57-
} catch (InstantiationException | IllegalAccessException | InvocationTargetException
58-
| NoSuchMethodException e) {
59-
throw new RuntimeException(e);
60-
}
61-
}
62-
63-
return module;
38+
public static void addSerializer(Class<? extends StdSerializer> serClass) {
39+
try {
40+
StdSerializer serializer = serClass.getConstructor().newInstance();
41+
serializers.addExactSerializer(serializer.handledType(), serializer);
42+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException
43+
| NoSuchMethodException e) {
44+
throw new RuntimeException(e);
6445
}
46+
}
6547

48+
public static void addDeserializer(Class<? extends StdDeserializer> deserClass) {
49+
try {
50+
StdDeserializer deserializer = deserClass.getConstructor().newInstance();
51+
mappingModule.addDeserializer(deserializer.handledType(), deserializer);
52+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException
53+
| NoSuchMethodException e) {
54+
throw new RuntimeException(e);
55+
}
6656
}
6757

6858
public static class ExactSerializers extends SimpleSerializers {

0 commit comments

Comments
 (0)