Prefer modified resources over the originals in TestCompiler
Previously, when the test compiler had been seeded with a resource file, any modifications to this resource performed during compilation would be lost as this original content would always be returned. This commit updates the DynamicJavaFileManager to always store the dynamic resource in the dynamicResourceFiles map, irrespective of whether it's being created afresh or from some existing resource content. This ensures that any modifications made to the resource can be retrieved later on. Similarly, DynamicClassLoader has been updated to prefer dynamic resource files over any original resource files. This ensures that the resource that it finds reflects any modifications that have been made to it. See gh-33850
This commit is contained in:
committed by
Stéphane Nicoll
parent
9b3cb15389
commit
f6e1a5de09
@@ -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 @@ class DynamicJavaFileManagerTests {
|
||||
"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);
|
||||
|
||||
@@ -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.Processor;
|
||||
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 @@ class TestCompilerTests {
|
||||
});
|
||||
}
|
||||
|
||||
@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 @@ class TestCompilerTests {
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user