diff --git a/plexus-compilers/plexus-compiler-javac/pom.xml b/plexus-compilers/plexus-compiler-javac/pom.xml
index 91c68b47..35f496dc 100644
--- a/plexus-compilers/plexus-compiler-javac/pom.xml
+++ b/plexus-compilers/plexus-compiler-javac/pom.xml
@@ -27,6 +27,11 @@
junit-jupiter-api
test
+
+ org.junit.jupiter
+ junit-jupiter-params
+ test
+
org.hamcrest
hamcrest
diff --git a/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java b/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java
index 12cace69..1e97f8e7 100644
--- a/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java
+++ b/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java
@@ -65,6 +65,7 @@
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.regex.Pattern;
import org.codehaus.plexus.compiler.AbstractCompiler;
import org.codehaus.plexus.compiler.CompilerConfiguration;
@@ -627,6 +628,16 @@ private static CompilerResult compileInProcess0(Class> javacClass, String[] ar
return new CompilerResult(success, messages);
}
+ // Match ~95% of existing JDK exception name patterns (last checked for JDK 21)
+ private static final Pattern STACK_TRACE_FIRST_LINE = Pattern.compile("^(?:[\\w+.-]+\\.)[\\w$]*?(?:"
+ + "Exception|Error|Throwable|Failure|Result|Abort|Fault|ThreadDeath|Overflow|Warning|"
+ + "NotSupported|NotFound|BadArgs|BadClassFile|Illegal|Invalid|Unexpected|Unchecked|Unmatched\\w+"
+ + ").*$");
+
+ // Match exception causes, existing and omitted stack trace elements
+ private static final Pattern STACK_TRACE_OTHER_LINE =
+ Pattern.compile("^(?:Caused by:\\s.*|\\s*at .*|\\s*\\.\\.\\.\\s\\d+\\smore)$");
+
/**
* Parse the output from the compiler into a list of CompilerMessage objects
*
@@ -643,13 +654,14 @@ static List parseModernStream(int exitCode, BufferedReader inpu
StringBuilder buffer = new StringBuilder();
boolean hasPointer = false;
+ int stackTraceLineCount = 0;
while (true) {
line = input.readLine();
if (line == null) {
// javac output not detected by other parsing
- // maybe better to ignore only the summary an mark the rest as error
+ // maybe better to ignore only the summary and mark the rest as error
String bufferAsString = buffer.toString();
if (buffer.length() > 0) {
if (bufferAsString.startsWith("javac:")) {
@@ -659,26 +671,44 @@ static List parseModernStream(int exitCode, BufferedReader inpu
} else if (hasPointer) {
// A compiler message remains in buffer at end of parse stream
errors.add(parseModernError(exitCode, bufferAsString));
+ } else if (stackTraceLineCount > 0) {
+ // Extract stack trace from end of buffer
+ String[] lines = bufferAsString.split("\\R");
+ int linesTotal = lines.length;
+ buffer = new StringBuilder();
+ int firstLine = linesTotal - stackTraceLineCount;
+
+ // Salvage Javac localized message 'javac.msg.bug' ("An exception has occurred in the
+ // compiler ... Please file a bug")
+ if (firstLine > 0) {
+ final String lineBeforeStackTrace = lines[firstLine - 1];
+ // One of those two URL substrings should always appear, without regard to JVM locale.
+ // TODO: Update, if the URL changes, last checked for JDK 21.
+ if (lineBeforeStackTrace.contains("java.sun.com/webapps/bugreport")
+ || lineBeforeStackTrace.contains("bugreport.java.com")) {
+ firstLine--;
+ }
+ }
+
+ // Note: For message 'javac.msg.proc.annotation.uncaught.exception' ("An annotation processor
+ // threw an uncaught exception"), there is no locale-independent substring, and the header is
+ // also multi-line. It was discarded in the removed method 'parseAnnotationProcessorStream',
+ // and we continue to do so.
+
+ for (int i = firstLine; i < linesTotal; i++) {
+ buffer.append(lines[i]).append(EOL);
+ }
+ errors.add(new CompilerMessage(buffer.toString(), CompilerMessage.Kind.ERROR));
}
}
return errors;
}
- // A compiler error occurred, treat everything that follows as part of the error.
- if (line.startsWith("An exception has occurred in the compiler")) {
- buffer = new StringBuilder();
-
- while (line != null) {
- buffer.append(line);
- buffer.append(EOL);
- line = input.readLine();
- }
-
- errors.add(new CompilerMessage(buffer.toString(), CompilerMessage.Kind.ERROR));
- return errors;
- } else if (line.startsWith("An annotation processor threw an uncaught exception.")) {
- CompilerMessage annotationProcessingError = parseAnnotationProcessorStream(input);
- errors.add(annotationProcessingError);
+ if (stackTraceLineCount == 0 && STACK_TRACE_FIRST_LINE.matcher(line).matches()
+ || STACK_TRACE_OTHER_LINE.matcher(line).matches()) {
+ stackTraceLineCount++;
+ } else {
+ stackTraceLineCount = 0;
}
// new error block?
@@ -714,21 +744,6 @@ static List parseModernStream(int exitCode, BufferedReader inpu
}
}
- private static CompilerMessage parseAnnotationProcessorStream(final BufferedReader input) throws IOException {
- String line = input.readLine();
- final StringBuilder buffer = new StringBuilder();
-
- while (line != null) {
- if (!line.startsWith("Consult the following stack trace for details.")) {
- buffer.append(line);
- buffer.append(EOL);
- }
- line = input.readLine();
- }
-
- return new CompilerMessage(buffer.toString(), CompilerMessage.Kind.ERROR);
- }
-
private static boolean isMisc(String line) {
return startsWithPrefix(line, MISC_PREFIXES);
}
diff --git a/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/ErrorMessageParserTest.java b/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/ErrorMessageParserTest.java
index bfc416a4..d8f01590 100644
--- a/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/ErrorMessageParserTest.java
+++ b/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/ErrorMessageParserTest.java
@@ -28,20 +28,25 @@
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Stream;
import org.codehaus.plexus.compiler.CompilerMessage;
import org.codehaus.plexus.util.Os;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.core.StringEndsWith.endsWith;
-import static org.hamcrest.core.StringStartsWith.startsWith;
/**
* @author Trygve Laugstøl
+ * @author Alexander Kriegisch
*/
public class ErrorMessageParserTest {
private static final String EOL = System.getProperty("line.separator");
@@ -775,19 +780,79 @@ public void testJava7Error() throws Exception {
assertThat(message2.getEndLine(), is(3));
}
- @Test
- public void testBugParade() throws Exception {
- String out = "An exception has occurred in the compiler (1.7.0_80). "
- + "Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. "
- + "Include your program and the following diagnostic in your report. Thank you." + EOL
- + "com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.util.Optional not found";
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("testBugParade_args")
+ public void testBugParade(String jdkAndLocale, String stackTraceHeader) throws Exception {
+ String stackTraceWithHeader = stackTraceHeader + stackTraceInternalCompilerError;
- List compilerErrors =
- JavacCompiler.parseModernStream(4, new BufferedReader(new StringReader(out)));
+ List compilerMessages =
+ JavacCompiler.parseModernStream(4, new BufferedReader(new StringReader(stackTraceWithHeader)));
- assertThat(compilerErrors, notNullValue());
+ assertThat(compilerMessages, notNullValue());
+ assertThat(compilerMessages, hasSize(1));
- assertThat(compilerErrors.size(), is(1));
+ String message = compilerMessages.get(0).getMessage().replaceAll(EOL, "\n");
+ // Parser retains stack trace header
+ assertThat(message, startsWith(stackTraceHeader));
+ assertThat(message, endsWith(stackTraceInternalCompilerError));
+ }
+
+ private static final String stackTraceInternalCompilerError =
+ "\tat com.sun.tools.javac.comp.MemberEnter.baseEnv(MemberEnter.java:1388)\n"
+ + "\tat com.sun.tools.javac.comp.MemberEnter.complete(MemberEnter.java:1046)\n"
+ + "\tat com.sun.tools.javac.code.Symbol.complete(Symbol.java:574)\n"
+ + "\tat com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1037)\n"
+ + "\tat com.sun.tools.javac.code.Symbol$ClassSymbol.flags(Symbol.java:973)\n"
+ + "\tat com.sun.tools.javac.code.Symbol$ClassSymbol.getKind(Symbol.java:1101)\n"
+ + "\tat com.sun.tools.javac.code.Kinds.kindName(Kinds.java:162)\n"
+ + "\tat com.sun.tools.javac.comp.Check.duplicateError(Check.java:329)\n"
+ + "\tat com.sun.tools.javac.comp.Check.checkUnique(Check.java:3435)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.visitTypeParameter(Enter.java:454)\n"
+ + "\tat com.sun.tools.javac.tree.JCTree$JCTypeParameter.accept(JCTree.java:2224)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.classEnter(Enter.java:258)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.classEnter(Enter.java:272)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.visitClassDef(Enter.java:418)\n"
+ + "\tat com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.classEnter(Enter.java:258)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.classEnter(Enter.java:272)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.visitTopLevel(Enter.java:334)\n"
+ + "\tat com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:518)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.classEnter(Enter.java:258)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.classEnter(Enter.java:272)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.complete(Enter.java:486)\n"
+ + "\tat com.sun.tools.javac.comp.Enter.main(Enter.java:471)\n"
+ + "\tat com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:982)\n"
+ + "\tat com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:857)\n"
+ + "\tat com.sun.tools.javac.main.Main.compile(Main.java:523)\n"
+ + "\tat com.sun.tools.javac.main.Main.compile(Main.java:381)\n"
+ + "\tat com.sun.tools.javac.main.Main.compile(Main.java:370)\n"
+ + "\tat com.sun.tools.javac.main.Main.compile(Main.java:361)\n"
+ + "\tat com.sun.tools.javac.Main.compile(Main.java:56)\n"
+ + "\tat com.sun.tools.javac.Main.main(Main.java:42)\n";
+
+ private static Stream testBugParade_args() {
+ return Stream.of(
+ Arguments.of(
+ "JDK 8 English",
+ "An exception has occurred in the compiler ({0}). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.\n"),
+ Arguments.of(
+ "JDK 8 Japanese",
+ "コンパイラで例外が発生しました({0})。Bug Paradeで重複がないかをご確認のうえ、Java Developer Connection (http://java.sun.com/webapps/bugreport)でbugの登録をお願いいたします。レポートには、そのプログラムと下記の診断内容を含めてください。ご協力ありがとうございます。\n"),
+ Arguments.of(
+ "JDK 8 Chinese",
+ "编译器 ({0}) 中出现异常错误。 如果在 Bug Parade 中没有找到该错误, 请在 Java Developer Connection (http://java.sun.com/webapps/bugreport) 中建立 Bug。请在报告中附上您的程序和以下诊断信息。谢谢。\n"),
+ Arguments.of(
+ "JDK 21 English",
+ "An exception has occurred in the compiler ({0}). Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.\n"),
+ Arguments.of(
+ "JDK 21 Japanese",
+ "コンパイラで例外が発生しました({0})。バグ・データベース(https://bugs.java.com)で重複がないかをご確認のうえ、Javaのバグ・レポート・ページ(https://bugreport.java.com)から、Javaコンパイラに対するバグの登録をお願いいたします。レポートには、該当のプログラム、次の診断内容、およびJavaコンパイラに渡されたパラメータをご入力ください。ご協力ありがとうございます。\n"),
+ Arguments.of(
+ "JDK 21 Chinese",
+ "编译器 ({0}) 中出现异常错误。如果在 Bug Database (https://bugs.java.com) 中没有找到有关该错误的 Java 编译器 Bug,请通过 Java Bug 报告页 (https://bugreport.java.com) 提交 Java 编译器 Bug。请在报告中附上您的程序、以下诊断信息以及传递到 Java 编译器的参数。谢谢。\n"),
+ Arguments.of(
+ "JDK 21 German",
+ "Im Compiler ({0}) ist eine Ausnahme aufgetreten. Erstellen Sie auf der Java-Seite zum Melden von Bugs (https://bugreport.java.com) einen Bugbericht, nachdem Sie die Bugdatenbank (https://bugs.java.com) auf Duplikate geprüft haben. Geben Sie in Ihrem Bericht Ihr Programm, die folgende Diagnose und die Parameter an, die Sie dem Java-Compiler übergeben haben. Vielen Dank.\n"));
}
@Test
diff --git a/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/JavacCompilerTest.java b/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/JavacCompilerTest.java
index c8edab96..8a182fcf 100644
--- a/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/JavacCompilerTest.java
+++ b/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/JavacCompilerTest.java
@@ -4,13 +4,20 @@
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
+import java.util.stream.Stream;
import org.codehaus.plexus.compiler.CompilerMessage;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.notNullValue;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -33,40 +40,67 @@
/**
* @author Olivier Lamy
+ * @author Alexander Kriegisch
*/
public class JavacCompilerTest extends AbstractJavacCompilerTest {
+ private static final String EOL = System.getProperty("line.separator");
+
@BeforeEach
public void setUp() {
super.setUp();
setForceJavacCompilerUse(true);
}
- @Test
- void parseModernStream_withAnnotationProcessingErrors() throws IOException {
- String input = "\n" + "\n"
- + "An annotation processor threw an uncaught exception.\n"
- + "Consult the following stack trace for details.\n"
- + "java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @0x1da51a35) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x1da51a35\n"
- + "\tat lombok.javac.apt.LombokProcessor.getJavacProcessingEnvironment(LombokProcessor.java:433)\n"
- + "\tat lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:92)\n"
- + "\tat lombok.core.AnnotationProcessor$JavacDescriptor.want(AnnotationProcessor.java:160)\n"
- + "\tat lombok.core.AnnotationProcessor.init(AnnotationProcessor.java:213)\n"
- + "\tat lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init(AnnotationProcessor.java:64)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.(JavacProcessingEnvironment.java:702)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:829)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:925)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1269)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1384)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1261)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)\n"
- + "\tat jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)\n";
-
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("testParseModernStream_withAnnotationProcessingErrors_args")
+ void testParseModernStream_withAnnotationProcessingErrors(String jdkAndLocale, String stackTraceHeader)
+ throws IOException {
+ String stackTraceWithHeader = stackTraceHeader + stackTraceAnnotationProcessingError;
List compilerMessages =
- JavacCompiler.parseModernStream(1, new BufferedReader(new StringReader(input)));
+ JavacCompiler.parseModernStream(1, new BufferedReader(new StringReader(stackTraceWithHeader)));
+ assertThat(compilerMessages, notNullValue());
assertThat(compilerMessages, hasSize(1));
+
+ String message = compilerMessages.get(0).getMessage().replaceAll(EOL, "\n");
+ // Parser does not retain stack trace header, because it is hard to identify in a locale-independent way
+ assertThat(message, not(startsWith(stackTraceHeader)));
+ assertThat(message, endsWith(stackTraceAnnotationProcessingError));
+ }
+
+ private static final String stackTraceAnnotationProcessingError =
+ "java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @0x1da51a35) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x1da51a35\n"
+ + "\tat lombok.javac.apt.LombokProcessor.getJavacProcessingEnvironment(LombokProcessor.java:433)\n"
+ + "\tat lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:92)\n"
+ + "\tat lombok.core.AnnotationProcessor$JavacDescriptor.want(AnnotationProcessor.java:160)\n"
+ + "\tat lombok.core.AnnotationProcessor.init(AnnotationProcessor.java:213)\n"
+ + "\tat lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init(AnnotationProcessor.java:64)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.(JavacProcessingEnvironment.java:702)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:829)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:925)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1269)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1384)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1261)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)\n"
+ + "\tat jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)\n";
+
+ private static Stream testParseModernStream_withAnnotationProcessingErrors_args() {
+ return Stream.of(
+ Arguments.of(
+ "JDK 8 English",
+ "\n\nAn annotation processor threw an uncaught exception.\nConsult the following stack trace for details.\n\n"),
+ Arguments.of("JDK 8 Japanese", "\n\n注釈処理で捕捉されない例外がスローされました。\n詳細は次のスタック・トレースで調査してください。\n\n"),
+ Arguments.of("JDK 8 Chinese", "\n\n注释处理程序抛出未捕获的异常错误。\n有关详细信息, 请参阅以下堆栈跟踪。\n\n"),
+ Arguments.of(
+ "JDK 21 English",
+ "\n\nAn annotation processor threw an uncaught exception.\nConsult the following stack trace for details.\n\n"),
+ Arguments.of("JDK 21 Japanese", "\n\n注釈処理で捕捉されない例外がスローされました。\n詳細は次のスタックトレースで調査してください。\n\n"),
+ Arguments.of("JDK 21 Chinese", "\n\n批注处理程序抛出未捕获的异常错误。\n有关详细信息, 请参阅以下堆栈跟踪。\n\n"),
+ Arguments.of(
+ "JDK 21 German",
+ "\n\nEin Annotationsprozessor hat eine nicht abgefangene Ausnahme ausgelöst.\nDetails finden Sie im folgenden Stacktrace.\n\n"));
}
}