Rename @CompileWithTargetClassAccess
Rename `@CompileWithTargetClassAccess` to `@CompileWithForkedClassLoaderClassLoader`. Closes gh-29173
This commit is contained in:
parent
7168141504
commit
cc7552ec61
|
@ -27,7 +27,7 @@ import org.springframework.aot.generate.MethodReference;
|
||||||
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
||||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||||
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
|
import org.springframework.aot.test.generate.compile.CompileWithForkedClassLoader;
|
||||||
import org.springframework.aot.test.generate.compile.Compiled;
|
import org.springframework.aot.test.generate.compile.Compiled;
|
||||||
import org.springframework.aot.test.generate.compile.TestCompiler;
|
import org.springframework.aot.test.generate.compile.TestCompiler;
|
||||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||||
|
@ -85,7 +85,7 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
void contributeWhenPackagePrivateFieldInjectionInjectsUsingConsumer() {
|
void contributeWhenPackagePrivateFieldInjectionInjectsUsingConsumer() {
|
||||||
Environment environment = new StandardEnvironment();
|
Environment environment = new StandardEnvironment();
|
||||||
this.beanFactory.registerSingleton("environment", environment);
|
this.beanFactory.registerSingleton("environment", environment);
|
||||||
|
@ -122,7 +122,7 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
void contributeWhenPackagePrivateMethodInjectionInjectsUsingConsumer() {
|
void contributeWhenPackagePrivateMethodInjectionInjectsUsingConsumer() {
|
||||||
Environment environment = new StandardEnvironment();
|
Environment environment = new StandardEnvironment();
|
||||||
this.beanFactory.registerSingleton("environment", environment);
|
this.beanFactory.registerSingleton("environment", environment);
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.springframework.aot.generate.GenerationContext;
|
||||||
import org.springframework.aot.generate.MethodReference;
|
import org.springframework.aot.generate.MethodReference;
|
||||||
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
||||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||||
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
|
import org.springframework.aot.test.generate.compile.CompileWithForkedClassLoader;
|
||||||
import org.springframework.aot.test.generate.compile.Compiled;
|
import org.springframework.aot.test.generate.compile.Compiled;
|
||||||
import org.springframework.aot.test.generate.compile.TestCompiler;
|
import org.springframework.aot.test.generate.compile.TestCompiler;
|
||||||
import org.springframework.aot.test.generate.file.SourceFile;
|
import org.springframework.aot.test.generate.file.SourceFile;
|
||||||
|
@ -387,7 +387,7 @@ class BeanDefinitionMethodGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
void generateBeanDefinitionMethodWhenPackagePrivateBean() {
|
void generateBeanDefinitionMethodWhenPackagePrivateBean() {
|
||||||
RegisteredBean registeredBean = registerBean(
|
RegisteredBean registeredBean = registerBean(
|
||||||
new RootBeanDefinition(PackagePrivateTestBean.class));
|
new RootBeanDefinition(PackagePrivateTestBean.class));
|
||||||
|
|
|
@ -26,8 +26,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation that registers a JUnit Jupiter extension for test classes or test
|
* Annotation that registers a JUnit Jupiter extension for test classes or test
|
||||||
* methods that need a {@link TestCompiler} with non-public access to target
|
* methods that need to use a forked classloader with compiled code.
|
||||||
* classes.
|
|
||||||
*
|
*
|
||||||
* <p>The extension allows the compiler to define classes without polluting the
|
* <p>The extension allows the compiler to define classes without polluting the
|
||||||
* test {@link ClassLoader}.
|
* test {@link ClassLoader}.
|
||||||
|
@ -45,6 +44,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
@Documented
|
@Documented
|
||||||
@ExtendWith(CompileWithTargetClassAccessExtension.class)
|
@ExtendWith(CompileWithForkedClassLoaderExtension.class)
|
||||||
public @interface CompileWithTargetClassAccess {
|
public @interface CompileWithForkedClassLoader {
|
||||||
}
|
}
|
|
@ -26,29 +26,38 @@ import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ClassLoader} implementation to support
|
* {@link ClassLoader} implementation to support
|
||||||
* {@link CompileWithTargetClassAccess @CompileWithTargetClassAccess}.
|
* {@link CompileWithForkedClassLoader @CompileWithForkedClassLoader}.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @author Stephane Nicoll
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
final class CompileWithTargetClassAccessClassLoader extends ClassLoader {
|
final class CompileWithForkedClassLoaderClassLoader extends ClassLoader {
|
||||||
|
|
||||||
private final ClassLoader testClassLoader;
|
private final ClassLoader testClassLoader;
|
||||||
|
|
||||||
private Function<String, byte[]> classResourceLookup = name -> null;
|
private Function<String, byte[]> classResourceLookup = name -> null;
|
||||||
|
|
||||||
|
|
||||||
public CompileWithTargetClassAccessClassLoader(ClassLoader testClassLoader) {
|
public CompileWithForkedClassLoaderClassLoader(ClassLoader testClassLoader) {
|
||||||
super(testClassLoader.getParent());
|
super(testClassLoader.getParent());
|
||||||
this.testClassLoader = testClassLoader;
|
this.testClassLoader = testClassLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked reflectively by DynamicClassLoader constructor
|
// Invoked reflectively by DynamicClassLoader
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
void setClassResourceLookup(Function<String, byte[]> classResourceLookup) {
|
void setClassResourceLookup(Function<String, byte[]> classResourceLookup) {
|
||||||
this.classResourceLookup = classResourceLookup;
|
this.classResourceLookup = classResourceLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoked reflectively by DynamicClassLoader
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
Class<?> defineDynamicClass(String name, byte[] b, int off, int len) {
|
||||||
|
return super.defineClass(name, b, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||||
if (name.startsWith("org.junit") || name.startsWith("org.testng")) {
|
if (name.startsWith("org.junit") || name.startsWith("org.testng")) {
|
||||||
|
@ -82,13 +91,6 @@ final class CompileWithTargetClassAccessClassLoader extends ClassLoader {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked reflectively by DynamicClassLoader.findDefineClassMethod(ClassLoader)
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
Class<?> defineClassWithTargetAccess(String name, byte[] b, int off, int len) {
|
|
||||||
return super.defineClass(name, b, off, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Enumeration<URL> findResources(String name) throws IOException {
|
protected Enumeration<URL> findResources(String name) throws IOException {
|
||||||
return this.testClassLoader.getResources(name);
|
return this.testClassLoader.getResources(name);
|
|
@ -34,14 +34,14 @@ import static org.junit.platform.launcher.EngineFilter.includeEngines;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JUnit Jupiter {@link InvocationInterceptor} to support
|
* JUnit Jupiter {@link InvocationInterceptor} to support
|
||||||
* {@link CompileWithTargetClassAccess @CompileWithTargetClassAccess}.
|
* {@link CompileWithForkedClassLoader @CompileWithForkedClassLoader}.
|
||||||
*
|
*
|
||||||
* @author Christoph Dreis
|
* @author Christoph Dreis
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
class CompileWithTargetClassAccessExtension implements InvocationInterceptor {
|
class CompileWithForkedClassLoaderExtension implements InvocationInterceptor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interceptBeforeAllMethod(Invocation<Void> invocation,
|
public void interceptBeforeAllMethod(Invocation<Void> invocation,
|
||||||
|
@ -105,7 +105,7 @@ class CompileWithTargetClassAccessExtension implements InvocationInterceptor {
|
||||||
Class<?> testClass = extensionContext.getRequiredTestClass();
|
Class<?> testClass = extensionContext.getRequiredTestClass();
|
||||||
ClassLoader classLoader = testClass.getClassLoader();
|
ClassLoader classLoader = testClass.getClassLoader();
|
||||||
return classLoader.getClass().getName()
|
return classLoader.getClass().getName()
|
||||||
.equals(CompileWithTargetClassAccessClassLoader.class.getName());
|
.equals(CompileWithForkedClassLoaderClassLoader.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runTestWithModifiedClassPath(
|
private void runTestWithModifiedClassPath(
|
||||||
|
@ -115,7 +115,7 @@ class CompileWithTargetClassAccessExtension implements InvocationInterceptor {
|
||||||
Class<?> testClass = extensionContext.getRequiredTestClass();
|
Class<?> testClass = extensionContext.getRequiredTestClass();
|
||||||
Method testMethod = invocationContext.getExecutable();
|
Method testMethod = invocationContext.getExecutable();
|
||||||
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
ClassLoader forkedClassPathClassLoader = new CompileWithTargetClassAccessClassLoader(
|
ClassLoader forkedClassPathClassLoader = new CompileWithForkedClassLoaderClassLoader(
|
||||||
testClass.getClassLoader());
|
testClass.getClassLoader());
|
||||||
Thread.currentThread().setContextClassLoader(forkedClassPathClassLoader);
|
Thread.currentThread().setContextClassLoader(forkedClassPathClassLoader);
|
||||||
try {
|
try {
|
|
@ -63,14 +63,14 @@ public class DynamicClassLoader extends ClassLoader {
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.compiledClasses = compiledClasses;
|
this.compiledClasses = compiledClasses;
|
||||||
Class<? extends ClassLoader> parentClass = parent.getClass();
|
Class<? extends ClassLoader> parentClass = parent.getClass();
|
||||||
if (parentClass.getName().equals(CompileWithTargetClassAccessClassLoader.class.getName())) {
|
if (parentClass.getName().equals(CompileWithForkedClassLoaderClassLoader.class.getName())) {
|
||||||
Method setClassResourceLookupMethod = ReflectionUtils.findMethod(parentClass,
|
Method setClassResourceLookupMethod = ReflectionUtils.findMethod(parentClass,
|
||||||
"setClassResourceLookup", Function.class);
|
"setClassResourceLookup", Function.class);
|
||||||
ReflectionUtils.makeAccessible(setClassResourceLookupMethod);
|
ReflectionUtils.makeAccessible(setClassResourceLookupMethod);
|
||||||
ReflectionUtils.invokeMethod(setClassResourceLookupMethod,
|
ReflectionUtils.invokeMethod(setClassResourceLookupMethod,
|
||||||
getParent(), (Function<String, byte[]>) this::findClassBytes);
|
getParent(), (Function<String, byte[]>) this::findClassBytes);
|
||||||
this.defineClassMethod = ReflectionUtils.findMethod(parentClass,
|
this.defineClassMethod = ReflectionUtils.findMethod(parentClass,
|
||||||
"defineClassWithTargetAccess", String.class, byte[].class, int.class, int.class);
|
"defineDynamicClass", String.class, byte[].class, int.class, int.class);
|
||||||
ReflectionUtils.makeAccessible(this.defineClassMethod);
|
ReflectionUtils.makeAccessible(this.defineClassMethod);
|
||||||
this.compiledClasses.forEach((name, file) -> defineClass(name, file.getBytes()));
|
this.compiledClasses.forEach((name, file) -> defineClass(name, file.getBytes()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,7 +276,7 @@ public final class TestCompiler {
|
||||||
}
|
}
|
||||||
catch (IllegalAccessError ex) {
|
catch (IllegalAccessError ex) {
|
||||||
throw new IllegalAccessError(ex.getMessage() + ". " +
|
throw new IllegalAccessError(ex.getMessage() + ". " +
|
||||||
"For non-public access ensure you annotate your test class or test method with @CompileWithTargetClassAccess");
|
"For non-public access ensure you annotate your test class or test method with @CompileWithForkedClassLoader");
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
Thread.currentThread().setContextClassLoader(previousClassLoader);
|
Thread.currentThread().setContextClassLoader(previousClassLoader);
|
||||||
|
|
|
@ -206,7 +206,7 @@ class TestCompilerTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
void compiledCodeCanAccessExistingPackagePrivateClassIfAnnotated() throws LinkageError {
|
void compiledCodeCanAccessExistingPackagePrivateClassIfAnnotated() throws LinkageError {
|
||||||
SourceFiles sourceFiles = SourceFiles.of(SourceFile.of("""
|
SourceFiles sourceFiles = SourceFiles.of(SourceFile.of("""
|
||||||
package com.example;
|
package com.example;
|
||||||
|
@ -240,7 +240,7 @@ class TestCompilerTests {
|
||||||
assertThatExceptionOfType(IllegalAccessError.class)
|
assertThatExceptionOfType(IllegalAccessError.class)
|
||||||
.isThrownBy(() -> TestCompiler.forSystem().compile(sourceFiles,
|
.isThrownBy(() -> TestCompiler.forSystem().compile(sourceFiles,
|
||||||
compiled -> compiled.getInstance(PublicInterface.class, "com.example.Test").perform()))
|
compiled -> compiled.getInstance(PublicInterface.class, "com.example.Test").perform()))
|
||||||
.withMessageContaining(ClassUtils.getShortName(CompileWithTargetClassAccess.class));
|
.withMessageContaining(ClassUtils.getShortName(CompileWithForkedClassLoader.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.aot.hint.TypeReference;
|
import org.springframework.aot.hint.TypeReference;
|
||||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||||
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
|
import org.springframework.aot.test.generate.compile.CompileWithForkedClassLoader;
|
||||||
import org.springframework.aot.test.generate.compile.Compiled;
|
import org.springframework.aot.test.generate.compile.Compiled;
|
||||||
import org.springframework.aot.test.generate.compile.TestCompiler;
|
import org.springframework.aot.test.generate.compile.TestCompiler;
|
||||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||||
|
@ -53,7 +53,7 @@ import static org.mockito.Mockito.mock;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
*/
|
*/
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
class PersistenceAnnotationBeanPostProcessorAotContributionTests {
|
class PersistenceAnnotationBeanPostProcessorAotContributionTests {
|
||||||
|
|
||||||
private DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
private DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||||
|
|
|
@ -37,7 +37,7 @@ import org.opentest4j.MultipleFailuresError;
|
||||||
import org.springframework.aot.AotDetector;
|
import org.springframework.aot.AotDetector;
|
||||||
import org.springframework.aot.generate.GeneratedFiles.Kind;
|
import org.springframework.aot.generate.GeneratedFiles.Kind;
|
||||||
import org.springframework.aot.generate.InMemoryGeneratedFiles;
|
import org.springframework.aot.generate.InMemoryGeneratedFiles;
|
||||||
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
|
import org.springframework.aot.test.generate.compile.CompileWithForkedClassLoader;
|
||||||
import org.springframework.aot.test.generate.compile.TestCompiler;
|
import org.springframework.aot.test.generate.compile.TestCompiler;
|
||||||
import org.springframework.test.context.aot.samples.basic.BasicSpringJupiterSharedConfigTests;
|
import org.springframework.test.context.aot.samples.basic.BasicSpringJupiterSharedConfigTests;
|
||||||
import org.springframework.test.context.aot.samples.basic.BasicSpringJupiterTests;
|
import org.springframework.test.context.aot.samples.basic.BasicSpringJupiterTests;
|
||||||
|
@ -54,7 +54,7 @@ import static org.junit.platform.launcher.TagFilter.excludeTags;
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
class AotIntegrationTests extends AbstractAotTests {
|
class AotIntegrationTests extends AbstractAotTests {
|
||||||
|
|
||||||
private static final String CLASSPATH_ROOT = "AotSmokeTests.classpath_root";
|
private static final String CLASSPATH_ROOT = "AotSmokeTests.classpath_root";
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.springframework.aot.generate.InMemoryGeneratedFiles;
|
||||||
import org.springframework.aot.hint.MemberCategory;
|
import org.springframework.aot.hint.MemberCategory;
|
||||||
import org.springframework.aot.hint.RuntimeHints;
|
import org.springframework.aot.hint.RuntimeHints;
|
||||||
import org.springframework.aot.hint.TypeReference;
|
import org.springframework.aot.hint.TypeReference;
|
||||||
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
|
import org.springframework.aot.test.generate.compile.CompileWithForkedClassLoader;
|
||||||
import org.springframework.aot.test.generate.compile.TestCompiler;
|
import org.springframework.aot.test.generate.compile.TestCompiler;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextInitializer;
|
import org.springframework.context.ApplicationContextInitializer;
|
||||||
|
@ -80,7 +80,7 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppC
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
@CompileWithTargetClassAccess
|
@CompileWithForkedClassLoader
|
||||||
class TestContextAotGeneratorTests extends AbstractAotTests {
|
class TestContextAotGeneratorTests extends AbstractAotTests {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<suppress files="Target_ClassFinder" checks="HideUtilityClassConstructor"/>
|
<suppress files="Target_ClassFinder" checks="HideUtilityClassConstructor"/>
|
||||||
|
|
||||||
<!-- spring-core-test -->
|
<!-- spring-core-test -->
|
||||||
<suppress files="CompileWithTargetClassAccess" checks="IllegalImport" id="bannedJUnitJupiterImports" />
|
<suppress files="CompileWithForkedClassLoader" checks="IllegalImport" id="bannedJUnitJupiterImports" />
|
||||||
<suppress files="org[\\/]springframework[\\/]aot[\\/]test[\\/]agent[\\/].+" checks="IllegalImport" id="bannedJUnitJupiterImports" />
|
<suppress files="org[\\/]springframework[\\/]aot[\\/]test[\\/]agent[\\/].+" checks="IllegalImport" id="bannedJUnitJupiterImports" />
|
||||||
|
|
||||||
<!-- spring-expression -->
|
<!-- spring-expression -->
|
||||||
|
|
Loading…
Reference in New Issue