Skip to content

Commit 3692a20

Browse files
committed
GH-364 - Register reflection metadata for ApplicationListenerMethodAdapter.
The maintain general compatibility with Spring Framework 6.0, we issue a few reflective inspections on ApplicationListenerMethodAdapter. To make this work properly in native images, we now register those methods for GraalVM reflection.
1 parent e2cc4fe commit 3692a20

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.modulith.events.aot;
17+
18+
import org.springframework.aot.hint.ExecutableMode;
19+
import org.springframework.aot.hint.RuntimeHints;
20+
import org.springframework.aot.hint.RuntimeHintsRegistrar;
21+
import org.springframework.context.ApplicationEvent;
22+
import org.springframework.context.event.ApplicationListenerMethodAdapter;
23+
import org.springframework.util.ReflectionUtils;
24+
25+
/**
26+
* @author Oliver Drotbohm
27+
*/
28+
public class ApplicationListenerMethodAdapterRuntimeHints implements RuntimeHintsRegistrar {
29+
30+
/*
31+
* (non-Javadoc)
32+
* @see org.springframework.aot.hint.RuntimeHintsRegistrar#registerHints(org.springframework.aot.hint.RuntimeHints, java.lang.ClassLoader)
33+
*/
34+
@Override
35+
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
36+
37+
var reflection = hints.reflection();
38+
39+
var method = ReflectionUtils.findMethod(ApplicationListenerMethodAdapter.class,
40+
"shouldHandle", ApplicationEvent.class);
41+
42+
if (method == null) {
43+
method = ReflectionUtils.findMethod(ApplicationListenerMethodAdapter.class,
44+
"shouldHandle", ApplicationEvent.class, Object[].class);
45+
}
46+
47+
if (method != null) {
48+
reflection.registerMethod(method, ExecutableMode.INVOKE);
49+
}
50+
}
51+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
22
org.springframework.modulith.events.aot.TransactionalEventListenerAotProcessor
3+
org.springframework.aot.hint.RuntimeHintsRegistrar=\
4+
org.springframework.modulith.events.aot.ApplicationListenerMethodAdapterRuntimeHints
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.modulith.events.aot;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
import static org.assertj.core.api.InstanceOfAssertFactories.*;
20+
21+
import org.junit.jupiter.api.Test;
22+
import org.springframework.aot.hint.ExecutableHint;
23+
import org.springframework.aot.hint.ExecutableMode;
24+
import org.springframework.aot.hint.RuntimeHints;
25+
import org.springframework.context.event.ApplicationListenerMethodAdapter;
26+
27+
/**
28+
* Unit tests for {@link ApplicationListenerMethodAdapterRuntimeHints}.
29+
*
30+
* @author Oliver Drotbohm
31+
*/
32+
class ApplicationListenerMethodAdapterRuntimeHintsUnitTests {
33+
34+
@Test // GH-364
35+
void registersMethodsForReflection() {
36+
37+
var hints = new RuntimeHints();
38+
39+
new ApplicationListenerMethodAdapterRuntimeHints()
40+
.registerHints(hints, getClass().getClassLoader());
41+
42+
var typeHint = hints.reflection()
43+
.getTypeHint(ApplicationListenerMethodAdapter.class);
44+
45+
assertThat(typeHint)
46+
.isNotNull()
47+
.extracting(it -> it.methods())
48+
.asInstanceOf(stream(ExecutableHint.class))
49+
.hasSize(1)
50+
.element(0)
51+
.satisfies(it -> {
52+
assertThat(it.getName()).isEqualTo("shouldHandle");
53+
assertThat(it.getMode()).isEqualTo(ExecutableMode.INVOKE);
54+
});
55+
}
56+
}

0 commit comments

Comments
 (0)