Skip to content

Commit 656dc54

Browse files
committed
Reject JDK proxy hint registration for sealed interfaces
Closes gh-28786
1 parent 5c2ee24 commit 656dc54

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

Diff for: spring-core/src/main/java/org/springframework/aot/hint/JdkProxyHint.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,12 @@ JdkProxyHint build() {
151151
}
152152

153153
private static List<TypeReference> toTypeReferences(Class<?>... proxiedInterfaces) {
154-
List<String> concreteTypes = Arrays.stream(proxiedInterfaces)
155-
.filter(candidate -> !candidate.isInterface()).map(Class::getName).toList();
156-
if (!concreteTypes.isEmpty()) {
157-
throw new IllegalArgumentException("Not an interface: " + concreteTypes);
154+
List<String> invalidTypes = Arrays.stream(proxiedInterfaces)
155+
.filter(candidate -> !candidate.isInterface() || candidate.isSealed())
156+
.map(Class::getName)
157+
.toList();
158+
if (!invalidTypes.isEmpty()) {
159+
throw new IllegalArgumentException("The following must be non-sealed interfaces: " + invalidTypes);
158160
}
159161
return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toList();
160162
}

Diff for: spring-core/src/test/java/org/springframework/aot/hint/ProxyHintsTests.java

+19-4
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,25 @@ class ProxyHintsTests {
3939

4040

4141
@Test
42-
void registerJdkProxyWithInterfaceClass() {
43-
this.proxyHints.registerJdkProxy(Function.class);
44-
assertThat(this.proxyHints.jdkProxies()).singleElement().satisfies(proxiedInterfaces(Function.class));
42+
void registerJdkProxyWithSealedInterface() {
43+
assertThatIllegalArgumentException()
44+
.isThrownBy(() -> this.proxyHints.registerJdkProxy(SealedInterface.class))
45+
.withMessageContaining(SealedInterface.class.getName());
4546
}
4647

4748
@Test
4849
void registerJdkProxyWithConcreteClass() {
49-
assertThatIllegalArgumentException().isThrownBy(() -> this.proxyHints.registerJdkProxy(String.class))
50+
assertThatIllegalArgumentException()
51+
.isThrownBy(() -> this.proxyHints.registerJdkProxy(String.class))
5052
.withMessageContaining(String.class.getName());
5153
}
5254

55+
@Test
56+
void registerJdkProxyWithInterface() {
57+
this.proxyHints.registerJdkProxy(Function.class);
58+
assertThat(this.proxyHints.jdkProxies()).singleElement().satisfies(proxiedInterfaces(Function.class));
59+
}
60+
5361
@Test
5462
void registerJdkProxyWithTypeReferences() {
5563
this.proxyHints.registerJdkProxy(TypeReference.of(Function.class), TypeReference.of("com.example.Advised"));
@@ -128,4 +136,11 @@ private static TypeReference[] toTypeReferences(Class<?>... proxiedInterfaces) {
128136
return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toArray(TypeReference[]::new);
129137
}
130138

139+
140+
sealed interface SealedInterface {
141+
}
142+
143+
static final class SealedClass implements SealedInterface {
144+
}
145+
131146
}

0 commit comments

Comments
 (0)