Skip to content

Commit dcbaece

Browse files
committed
Perform explicit class checks in ReactiveAdapterRegistry
In order to allow Spring Framework applications running as GraalVM native images, ReactiveAdapterRegistry should perform explicit class checks instead of catching Throwable in order to avoid UnsupportedFeatureError errors. Issue: SPR-17000
1 parent e485abb commit dcbaece

File tree

1 file changed

+26
-30
lines changed

1 file changed

+26
-30
lines changed

spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -63,41 +63,32 @@ public class ReactiveAdapterRegistry {
6363
*/
6464
public ReactiveAdapterRegistry() {
6565

66+
ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader();
67+
6668
// Reactor
6769
boolean reactorRegistered = false;
68-
try {
70+
if (ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader)) {
6971
new ReactorRegistrar().registerAdapters(this);
7072
reactorRegistered = true;
7173
}
72-
catch (Throwable ex) {
73-
// Ignore
74-
}
7574
this.reactorPresent = reactorRegistered;
7675

7776
// RxJava1
78-
try {
77+
if (ClassUtils.isPresent("rx.Observable", classLoader)) {
7978
new RxJava1Registrar().registerAdapters(this);
8079
}
81-
catch (Throwable ex) {
82-
// Ignore
83-
}
8480

8581
// RxJava2
86-
try {
82+
if (ClassUtils.isPresent("io.reactivex.Flowable", classLoader)) {
8783
new RxJava2Registrar().registerAdapters(this);
8884
}
89-
catch (Throwable ex) {
90-
// Ignore
91-
}
9285

9386
// Java 9+ Flow.Publisher
94-
try {
87+
if (ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader)) {
9588
new ReactorJdkFlowAdapterRegistrar().registerAdapter(this);
9689
}
97-
catch (Throwable ex) {
98-
// Ignore for the time being...
99-
// We can fall back on "reactive-streams-flow-bridge" (once released)
100-
}
90+
// If not present, do nothing for the time being...
91+
// We can fall back on "reactive-streams-flow-bridge" (once released)
10192
}
10293

10394

@@ -276,24 +267,29 @@ void registerAdapters(ReactiveAdapterRegistry registry) {
276267

277268
private static class ReactorJdkFlowAdapterRegistrar {
278269

279-
void registerAdapter(ReactiveAdapterRegistry registry) throws Exception {
270+
void registerAdapter(ReactiveAdapterRegistry registry) {
280271
// TODO: remove reflection when build requires JDK 9+
281272

282-
String publisherName = "java.util.concurrent.Flow.Publisher";
283-
Class<?> publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader());
273+
try {
274+
String publisherName = "java.util.concurrent.Flow.Publisher";
275+
Class<?> publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader());
284276

285-
String adapterName = "reactor.adapter.JdkFlowAdapter";
286-
Class<?> flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader());
277+
String adapterName = "reactor.adapter.JdkFlowAdapter";
278+
Class<?> flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader());
287279

288-
Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass);
289-
Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class);
290-
Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty());
280+
Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass);
281+
Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class);
282+
Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty());
291283

292-
registry.registerReactiveType(
293-
ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow),
294-
source -> (Publisher<?>) ReflectionUtils.invokeMethod(toFluxMethod, null, source),
295-
publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher)
296-
);
284+
registry.registerReactiveType(
285+
ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow),
286+
source -> (Publisher<?>) ReflectionUtils.invokeMethod(toFluxMethod, null, source),
287+
publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher)
288+
);
289+
}
290+
catch (Throwable ex) {
291+
// Ignore
292+
}
297293
}
298294
}
299295

0 commit comments

Comments
 (0)