diff --git a/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicClassLoader.java b/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicClassLoader.java index 1dba5feb849..e5ff9a9411e 100644 --- a/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicClassLoader.java +++ b/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicClassLoader.java @@ -31,6 +31,7 @@ import java.util.function.Supplier; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** @@ -91,15 +92,7 @@ public class DynamicClassLoader extends ClassLoader { return super.findClass(name); } - @Nullable - private byte[] findClassBytes(String name) { - ClassFile classFile = this.classFiles.get(name); - if (classFile != null) { - return classFile.getContent(); - } - DynamicClassFileObject dynamicClassFile = this.dynamicClassFiles.get(name); - return (dynamicClassFile != null) ? dynamicClassFile.getBytes() : null; - } + private Class defineClass(String name, byte[] bytes) { if (this.defineClassMethod != null) { @@ -109,7 +102,6 @@ public class DynamicClassLoader extends ClassLoader { return defineClass(name, bytes, 0, bytes.length); } - @Override protected Enumeration findResources(String name) throws IOException { URL resource = findResource(name); @@ -122,6 +114,14 @@ public class DynamicClassLoader extends ClassLoader { @Override @Nullable protected URL findResource(String name) { + if (name.endsWith(ClassUtils.CLASS_FILE_SUFFIX)) { + String className = ClassUtils.convertResourcePathToClassName(name.substring(0, + name.length() - ClassUtils.CLASS_FILE_SUFFIX.length())); + byte[] classBytes = findClassBytes(className); + if (classBytes != null) { + return createResourceUrl(name, () -> classBytes); + } + } ResourceFile resourceFile = this.resourceFiles.get(name); if (resourceFile != null) { return createResourceUrl(resourceFile.getPath(), resourceFile::getBytes); @@ -133,6 +133,16 @@ public class DynamicClassLoader extends ClassLoader { return super.findResource(name); } + @Nullable + private byte[] findClassBytes(String name) { + ClassFile classFile = this.classFiles.get(name); + if (classFile != null) { + return classFile.getContent(); + } + DynamicClassFileObject dynamicClassFile = this.dynamicClassFiles.get(name); + return (dynamicClassFile != null) ? dynamicClassFile.getBytes() : null; + } + private URL createResourceUrl(String name, Supplier bytesSupplier) { try { return new URL(null, "resource:///" + name, diff --git a/spring-core-test/src/test/java/org/springframework/core/test/tools/TestCompilerTests.java b/spring-core-test/src/test/java/org/springframework/core/test/tools/TestCompilerTests.java index e2a97d501c3..63a3055c5ee 100644 --- a/spring-core-test/src/test/java/org/springframework/core/test/tools/TestCompilerTests.java +++ b/spring-core-test/src/test/java/org/springframework/core/test/tools/TestCompilerTests.java @@ -16,6 +16,7 @@ package org.springframework.core.test.tools; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -278,6 +279,15 @@ class TestCompilerTests { compiled.getInstance(PublicInterface.class, "com.example.Test").perform()).isEqualTo("Hello from subpackage")); } + @Test + void getResourceForCompiledBytecode() { + SourceFile sourceFile = SourceFile.of(HELLO_WORLD); + TestCompiler.forSystem().compile(sourceFile, compiled -> { + InputStream stream = compiled.getClassLoader().getResourceAsStream("com/example/Hello.class"); + assertThat(stream).isNotNull(); + }); + } + private void assertSuppliesHelloWorld(Compiled compiled) { assertThat(compiled.getInstance(Supplier.class).get()).isEqualTo("Hello World!"); }