diff --git a/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java b/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java index 5d4b04ea75b0..ba88738f2f21 100644 --- a/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java +++ b/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java @@ -53,6 +53,8 @@ public final class TestCompiler { private final JavaCompiler compiler; + private final Locale locale; + private final SourceFiles sourceFiles; private final ResourceFiles resourceFiles; @@ -64,12 +66,13 @@ public final class TestCompiler { private final List compilerOptions; - private TestCompiler(@Nullable ClassLoader classLoader, JavaCompiler compiler, - SourceFiles sourceFiles, ResourceFiles resourceFiles, ClassFiles classFiles, - List processors, List compilerOptions) { + private TestCompiler(@Nullable ClassLoader classLoader, JavaCompiler compiler, Locale locale, + SourceFiles sourceFiles, ResourceFiles resourceFiles, ClassFiles classFiles, List processors, + List compilerOptions) { this.classLoader = classLoader; this.compiler = compiler; + this.locale = locale; this.sourceFiles = sourceFiles; this.resourceFiles = resourceFiles; this.classFiles = classFiles; @@ -92,8 +95,9 @@ public static TestCompiler forSystem() { * @return a new {@code TestCompiler} instance */ public static TestCompiler forCompiler(JavaCompiler javaCompiler) { - return new TestCompiler(null, javaCompiler, SourceFiles.none(), - ResourceFiles.none(), ClassFiles.none(), Collections.emptyList(), Collections.emptyList()); + return new TestCompiler(null, javaCompiler, Locale.getDefault(), + SourceFiles.none(), ResourceFiles.none(), + ClassFiles.none(), Collections.emptyList(), Collections.emptyList()); } /** @@ -105,13 +109,26 @@ public TestCompiler with(UnaryOperator customizer) { return customizer.apply(this); } + /** + * Create a new {@code TestCompiler} instance that uses the specified {@link Locale} + * to render compiler messages. + * @param locale the locale to use + * @return a new {@code TestCompiler} instance + * @since 6.1 + */ + public TestCompiler withLocale(Locale locale) { + return new TestCompiler(this.classLoader, this.compiler, locale, + this.sourceFiles, this.resourceFiles, + this.classFiles, this.processors, this.compilerOptions); + } + /** * Create a new {@code TestCompiler} instance with additional source files. * @param sourceFiles the additional source files * @return a new {@code TestCompiler} instance */ public TestCompiler withSources(SourceFile... sourceFiles) { - return new TestCompiler(this.classLoader, this.compiler, + return new TestCompiler(this.classLoader, this.compiler, this.locale, this.sourceFiles.and(sourceFiles), this.resourceFiles, this.classFiles, this.processors, this.compilerOptions); } @@ -122,7 +139,7 @@ public TestCompiler withSources(SourceFile... sourceFiles) { * @return a new {@code TestCompiler} instance */ public TestCompiler withSources(Iterable sourceFiles) { - return new TestCompiler(this.classLoader, this.compiler, + return new TestCompiler(this.classLoader, this.compiler, this.locale, this.sourceFiles.and(sourceFiles), this.resourceFiles, this.classFiles, this.processors, this.compilerOptions); } @@ -133,7 +150,7 @@ public TestCompiler withSources(Iterable sourceFiles) { * @return a new {@code TestCompiler} instance */ public TestCompiler withSources(SourceFiles sourceFiles) { - return new TestCompiler(this.classLoader, this.compiler, + return new TestCompiler(this.classLoader, this.compiler, this.locale, this.sourceFiles.and(sourceFiles), this.resourceFiles, this.classFiles, this.processors, this.compilerOptions); } @@ -144,9 +161,9 @@ public TestCompiler withSources(SourceFiles sourceFiles) { * @return a new {@code TestCompiler} instance */ public TestCompiler withResources(ResourceFile... resourceFiles) { - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles.and(resourceFiles), this.classFiles, this.processors, - this.compilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles.and(resourceFiles), + this.classFiles, this.processors, this.compilerOptions); } /** @@ -155,9 +172,9 @@ public TestCompiler withResources(ResourceFile... resourceFiles) { * @return a new {@code TestCompiler} instance */ public TestCompiler withResources(Iterable resourceFiles) { - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles.and(resourceFiles), this.classFiles, this.processors, - this.compilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles.and(resourceFiles), + this.classFiles, this.processors, this.compilerOptions); } /** @@ -166,9 +183,9 @@ public TestCompiler withResources(Iterable resourceFiles) { * @return a new {@code TestCompiler} instance */ public TestCompiler withResources(ResourceFiles resourceFiles) { - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles.and(resourceFiles), this.classFiles, this.processors, - this.compilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles.and(resourceFiles), + this.classFiles, this.processors, this.compilerOptions); } /** @@ -177,9 +194,9 @@ public TestCompiler withResources(ResourceFiles resourceFiles) { * @return a new {@code TestCompiler} instance */ public TestCompiler withClasses(Iterable classFiles) { - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles, this.classFiles.and(classFiles), this.processors, - this.compilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles, this.classFiles.and(classFiles), + this.processors, this.compilerOptions); } /** @@ -190,8 +207,9 @@ public TestCompiler withClasses(Iterable classFiles) { public TestCompiler withProcessors(Processor... processors) { List mergedProcessors = new ArrayList<>(this.processors); mergedProcessors.addAll(Arrays.asList(processors)); - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles, this.classFiles, mergedProcessors, this.compilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles, this.classFiles, mergedProcessors, + this.compilerOptions); } /** @@ -202,8 +220,9 @@ public TestCompiler withProcessors(Processor... processors) { public TestCompiler withProcessors(Iterable processors) { List mergedProcessors = new ArrayList<>(this.processors); processors.forEach(mergedProcessors::add); - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles, this.classFiles, mergedProcessors, this.compilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles, this.classFiles, + mergedProcessors, this.compilerOptions); } /** @@ -215,8 +234,9 @@ public TestCompiler withProcessors(Iterable processors) { public TestCompiler withCompilerOptions(String... options) { List mergedCompilerOptions = Stream.concat(this.compilerOptions.stream(), Arrays.stream(options)).distinct().toList(); - return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles, - this.resourceFiles, this.classFiles, this.processors, mergedCompilerOptions); + return new TestCompiler(this.classLoader, this.compiler, this.locale, + this.sourceFiles, this.resourceFiles, this.classFiles, + this.processors, mergedCompilerOptions); } /** @@ -308,7 +328,7 @@ private DynamicClassLoader compile() { DynamicJavaFileManager fileManager = new DynamicJavaFileManager( standardFileManager, classLoaderToUse, this.classFiles, this.resourceFiles); if (!this.sourceFiles.isEmpty()) { - Errors errors = new Errors(); + Errors errors = new Errors(this.locale); CompilationTask task = this.compiler.getTask(null, fileManager, errors, this.compilerOptions, null, compilationUnits); if (!this.processors.isEmpty()) { @@ -349,13 +369,19 @@ public TestCompiler printFiles(PrintStream printStream) { */ static class Errors implements DiagnosticListener { + private final Locale locale; + private final StringBuilder message = new StringBuilder(); + Errors(Locale locale) { + this.locale = locale; + } + @Override public void report(Diagnostic diagnostic) { if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { this.message.append('\n'); - this.message.append(diagnostic.getMessage(Locale.getDefault())); + this.message.append(diagnostic.getMessage(this.locale)); if (diagnostic.getSource() != null) { this.message.append(' '); this.message.append(diagnostic.getSource().getName()); 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 c921a728553d..c91cdcb3271b 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 @@ -19,6 +19,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.function.Supplier; @@ -170,8 +171,8 @@ public static void main(String[] args) { } """); assertThatExceptionOfType(CompilationException.class).isThrownBy( - () -> TestCompiler.forSystem().failOnWarning().withSources( - SourceFile.of(HELLO_DEPRECATED), main).compile(compiled -> { + () -> TestCompiler.forSystem().failOnWarning().withLocale(Locale.ENGLISH) + .withSources(SourceFile.of(HELLO_DEPRECATED), main).compile(compiled -> { })).withMessageContaining("warnings found and -Werror specified"); }