Reject JDK proxy hint registration for sealed interfaces

Closes gh-28786
This commit is contained in:
Sam Brannen 2022-07-11 17:45:24 +02:00
parent 5c2ee249b5
commit 656dc549b1
2 changed files with 25 additions and 8 deletions

View File

@ -151,10 +151,12 @@ public final class JdkProxyHint implements ConditionalHint {
} }
private static List<TypeReference> toTypeReferences(Class<?>... proxiedInterfaces) { private static List<TypeReference> toTypeReferences(Class<?>... proxiedInterfaces) {
List<String> concreteTypes = Arrays.stream(proxiedInterfaces) List<String> invalidTypes = Arrays.stream(proxiedInterfaces)
.filter(candidate -> !candidate.isInterface()).map(Class::getName).toList(); .filter(candidate -> !candidate.isInterface() || candidate.isSealed())
if (!concreteTypes.isEmpty()) { .map(Class::getName)
throw new IllegalArgumentException("Not an interface: " + concreteTypes); .toList();
if (!invalidTypes.isEmpty()) {
throw new IllegalArgumentException("The following must be non-sealed interfaces: " + invalidTypes);
} }
return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toList(); return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toList();
} }

View File

@ -39,17 +39,25 @@ class ProxyHintsTests {
@Test @Test
void registerJdkProxyWithInterfaceClass() { void registerJdkProxyWithSealedInterface() {
this.proxyHints.registerJdkProxy(Function.class); assertThatIllegalArgumentException()
assertThat(this.proxyHints.jdkProxies()).singleElement().satisfies(proxiedInterfaces(Function.class)); .isThrownBy(() -> this.proxyHints.registerJdkProxy(SealedInterface.class))
.withMessageContaining(SealedInterface.class.getName());
} }
@Test @Test
void registerJdkProxyWithConcreteClass() { void registerJdkProxyWithConcreteClass() {
assertThatIllegalArgumentException().isThrownBy(() -> this.proxyHints.registerJdkProxy(String.class)) assertThatIllegalArgumentException()
.isThrownBy(() -> this.proxyHints.registerJdkProxy(String.class))
.withMessageContaining(String.class.getName()); .withMessageContaining(String.class.getName());
} }
@Test
void registerJdkProxyWithInterface() {
this.proxyHints.registerJdkProxy(Function.class);
assertThat(this.proxyHints.jdkProxies()).singleElement().satisfies(proxiedInterfaces(Function.class));
}
@Test @Test
void registerJdkProxyWithTypeReferences() { void registerJdkProxyWithTypeReferences() {
this.proxyHints.registerJdkProxy(TypeReference.of(Function.class), TypeReference.of("com.example.Advised")); this.proxyHints.registerJdkProxy(TypeReference.of(Function.class), TypeReference.of("com.example.Advised"));
@ -128,4 +136,11 @@ class ProxyHintsTests {
return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toArray(TypeReference[]::new); return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toArray(TypeReference[]::new);
} }
sealed interface SealedInterface {
}
static final class SealedClass implements SealedInterface {
}
} }