Allow target type of a cglib proxy to be visible

This commit updates the hints of a Cglib proxy's target type so that
methods can be invoked and constructors can be introspected. The former
is needed as a cglib proxy invokes the target type via reflection. As
for that latter, this is required at least by
Enhancer#filterConstructors.

See gh-28954
This commit is contained in:
Stephane Nicoll
2022-08-16 07:32:42 +02:00
parent c58c827291
commit 9a1b7c5e47
2 changed files with 36 additions and 5 deletions

View File

@@ -30,6 +30,7 @@ import org.springframework.core.io.InputStreamSource;
import org.springframework.core.testfixture.aot.generate.TestGenerationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link GeneratedClassHandler}.
@@ -50,8 +51,8 @@ class GeneratedClassHandlerTests {
}
@Test
void handlerGenerateRuntimeHints() {
String className = "com.example.Test$$Proxy$$1";
void handlerGenerateRuntimeHintsForProxy() {
String className = "com.example.Test$$SpringCGLIB$$0";
this.handler.accept(className, TEST_CONTENT);
assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of(className))
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
@@ -59,14 +60,31 @@ class GeneratedClassHandlerTests {
.accepts(this.generationContext.getRuntimeHints());
}
@Test
void handlerGenerateRuntimeHintsForTargetType() {
String className = "com.example.Test$$SpringCGLIB$$0";
this.handler.accept(className, TEST_CONTENT);
assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of("com.example.Test"))
.withMemberCategories(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_DECLARED_METHODS))
.accepts(this.generationContext.getRuntimeHints());
}
@Test
void handlerFailsWithInvalidProxyClassName() {
String className = "com.example.Test$$AnotherProxy$$0";
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.accept(className, TEST_CONTENT))
.withMessageContaining("Failed to extract target type");
}
@Test
void handlerRegisterGeneratedClass() throws IOException {
String className = "com.example.Test$$Proxy$$1";
String className = "com.example.Test$$SpringCGLIB$$0";
this.handler.accept(className, TEST_CONTENT);
InMemoryGeneratedFiles generatedFiles = this.generationContext.getGeneratedFiles();
assertThat(generatedFiles.getGeneratedFiles(Kind.SOURCE)).isEmpty();
assertThat(generatedFiles.getGeneratedFiles(Kind.RESOURCE)).isEmpty();
String expectedPath = "com/example/Test$$Proxy$$1.class";
String expectedPath = "com/example/Test$$SpringCGLIB$$0.class";
assertThat(generatedFiles.getGeneratedFiles(Kind.CLASS)).containsOnlyKeys(expectedPath);
assertContent(generatedFiles.getGeneratedFiles(Kind.CLASS).get(expectedPath), TEST_CONTENT);
}