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 73b88758a007..c55d66401192 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -121,14 +121,14 @@ protected URL findResource(String name) { return createResourceUrl(name, () -> classBytes); } } - ResourceFile resourceFile = this.resourceFiles.get(name); - if (resourceFile != null) { - return createResourceUrl(resourceFile.getPath(), resourceFile::getBytes); - } DynamicResourceFileObject dynamicResourceFile = this.dynamicResourceFiles.get(name); if (dynamicResourceFile != null && dynamicResourceFile.getBytes() != null) { return createResourceUrl(dynamicResourceFile.getName(), dynamicResourceFile::getBytes); } + ResourceFile resourceFile = this.resourceFiles.get(name); + if (resourceFile != null) { + return createResourceUrl(resourceFile.getPath(), resourceFile::getBytes); + } return super.findResource(name); } diff --git a/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicJavaFileManager.java b/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicJavaFileManager.java index f359069e0cc6..4ac7da9ef3d5 100644 --- a/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicJavaFileManager.java +++ b/spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicJavaFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,13 +70,12 @@ public ClassLoader getClassLoader(Location location) { } @Override - public FileObject getFileForOutput(Location location, String packageName, - String relativeName, FileObject sibling) { - ResourceFile resourceFile = this.resourceFiles.get(relativeName); - if (resourceFile != null) { - return new DynamicResourceFileObject(relativeName, resourceFile.getContent()); - } - return this.dynamicResourceFiles.computeIfAbsent(relativeName, DynamicResourceFileObject::new); + public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) { + return this.dynamicResourceFiles.computeIfAbsent(relativeName, name -> { + ResourceFile resourceFile = this.resourceFiles.get(name); + return (resourceFile != null) ? new DynamicResourceFileObject(name, resourceFile.getContent()) + : new DynamicResourceFileObject(name); + }); } @Override diff --git a/spring-core-test/src/test/java/org/springframework/core/test/tools/DynamicJavaFileManagerTests.java b/spring-core-test/src/test/java/org/springframework/core/test/tools/DynamicJavaFileManagerTests.java index 474c506bf702..b32813b26a13 100644 --- a/spring-core-test/src/test/java/org/springframework/core/test/tools/DynamicJavaFileManagerTests.java +++ b/spring-core-test/src/test/java/org/springframework/core/test/tools/DynamicJavaFileManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.core.test.tools; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.util.EnumSet; @@ -154,6 +155,23 @@ void getFileForOutputReturnsFile() throws Exception { "META-INF/second.properties"); } + @Test + void existingResourceFileCanBeUpdated() throws IOException { + try (InputStream input = getResourceOne().openInputStream()) { + assertThat(input).hasContent("a"); + } + try (OutputStream output = getResourceOne().openOutputStream()) { + output.write('b'); + } + try (InputStream input = getResourceOne().openInputStream()) { + assertThat(input).hasContent("b"); + } + } + + private FileObject getResourceOne() { + return this.fileManager.getFileForOutput(this.location, "", "com/example/one/resource.one", null); + } + private void writeDummyBytecode(JavaFileObject fileObject) throws IOException { try (OutputStream outputStream = fileObject.openOutputStream()) { StreamUtils.copy(DUMMY_BYTECODE, outputStream); 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 48bd7e8df73e..504c56995598 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,10 @@ package org.springframework.core.test.tools; +import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -27,6 +30,8 @@ import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.TypeElement; +import javax.tools.FileObject; +import javax.tools.StandardLocation; import com.example.PublicInterface; import org.junit.jupiter.api.Test; @@ -367,6 +372,14 @@ void getResourceForCompiledBytecode() { }); } + @Test + void getUpdatedResourceAsStream() { + SourceFile sourceFile = SourceFile.of(HELLO_WORLD); + TestCompiler.forSystem().withResources(ResourceFile.of("com/example/resource", new byte[] { 'a' })) + .withProcessors(new ResourceModifyingProcessor()).compile(sourceFile, compiled -> assertThat( + compiled.getClassLoader().getResourceAsStream("com/example/resource")).hasContent("b")); + } + private void assertSuppliesHelloWorld(Compiled compiled) { assertThat(compiled.getInstance(Supplier.class).get()).isEqualTo("Hello World!"); } @@ -392,4 +405,26 @@ public List<TypeElement> getProcessedAnnotations() { } } + @SupportedAnnotationTypes("java.lang.Deprecated") + static class ResourceModifyingProcessor extends AbstractProcessor { + + @Override + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + try { + FileObject resource = this.processingEnv.getFiler() + .createResource(StandardLocation.CLASS_OUTPUT, "", "com/example/resource"); + try (OutputStream output = resource.openOutputStream()) { + output.write('b'); + } + } + catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + return true; + } + + } + }