65
65
import java .util .Properties ;
66
66
import java .util .StringTokenizer ;
67
67
import java .util .concurrent .ConcurrentLinkedDeque ;
68
+ import java .util .regex .Pattern ;
68
69
69
70
import org .codehaus .plexus .compiler .AbstractCompiler ;
70
71
import org .codehaus .plexus .compiler .CompilerConfiguration ;
@@ -627,6 +628,11 @@ private static CompilerResult compileInProcess0(Class<?> javacClass, String[] ar
627
628
return new CompilerResult (success , messages );
628
629
}
629
630
631
+ private static final Pattern STACK_TRACE_FIRST_LINE =
632
+ Pattern .compile ("^(?:[\\ w+.-]+\\ .)[\\ w$]*?(?:Exception|Error|Throwable|Failure).*$" );
633
+ private static final Pattern STACK_TRACE_OTHER_LINE =
634
+ Pattern .compile ("^(?:Caused by:\\ s.*|\\ s*at .*|\\ s*\\ .\\ .\\ .\\ s\\ d+\\ smore)$" );
635
+
630
636
/**
631
637
* Parse the output from the compiler into a list of CompilerMessage objects
632
638
*
@@ -643,6 +649,7 @@ static List<CompilerMessage> parseModernStream(int exitCode, BufferedReader inpu
643
649
StringBuilder buffer = new StringBuilder ();
644
650
645
651
boolean hasPointer = false ;
652
+ int stackTraceLineCount = 0 ;
646
653
647
654
while (true ) {
648
655
line = input .readLine ();
@@ -659,26 +666,44 @@ static List<CompilerMessage> parseModernStream(int exitCode, BufferedReader inpu
659
666
} else if (hasPointer ) {
660
667
// A compiler message remains in buffer at end of parse stream
661
668
errors .add (parseModernError (exitCode , bufferAsString ));
669
+ } else if (stackTraceLineCount > 0 ) {
670
+ // Extract stack trace from end of buffer
671
+ String [] lines = bufferAsString .split ("\\ R" );
672
+ int linesTotal = lines .length ;
673
+ buffer = new StringBuilder ();
674
+ int firstLine = linesTotal - stackTraceLineCount ;
675
+
676
+ // Salvage Javac localized message 'javac.msg.bug' ("An exception has occurred in the
677
+ // compiler ... Please file a bug")
678
+ if (firstLine > 0 ) {
679
+ final String lineBeforeStackTrace = lines [firstLine - 1 ];
680
+ // One of those two URL substrings should always appear, without regard to JVM locale.
681
+ // TODO: Update, if the URL changes, last checked for JDK 21.
682
+ if (lineBeforeStackTrace .contains ("java.sun.com/webapps/bugreport" )
683
+ || lineBeforeStackTrace .contains ("bugreport.java.com" )) {
684
+ firstLine --;
685
+ }
686
+ }
687
+
688
+ // Note: For message 'javac.msg.proc.annotation.uncaught.exception' ("An annotation processor
689
+ // threw an uncaught exception"), there is no locale-independent substring, and the header is
690
+ // also multi-line. It was discarded in the removed method 'parseAnnotationProcessorStream',
691
+ // and we continue to do so.
692
+
693
+ for (int i = firstLine ; i < linesTotal ; i ++) {
694
+ buffer .append (lines [i ]).append (EOL );
695
+ }
696
+ errors .add (new CompilerMessage (buffer .toString (), CompilerMessage .Kind .ERROR ));
662
697
}
663
698
}
664
699
return errors ;
665
700
}
666
701
667
- // A compiler error occurred, treat everything that follows as part of the error.
668
- if (line .startsWith ("An exception has occurred in the compiler" )) {
669
- buffer = new StringBuilder ();
670
-
671
- while (line != null ) {
672
- buffer .append (line );
673
- buffer .append (EOL );
674
- line = input .readLine ();
675
- }
676
-
677
- errors .add (new CompilerMessage (buffer .toString (), CompilerMessage .Kind .ERROR ));
678
- return errors ;
679
- } else if (line .startsWith ("An annotation processor threw an uncaught exception." )) {
680
- CompilerMessage annotationProcessingError = parseAnnotationProcessorStream (input );
681
- errors .add (annotationProcessingError );
702
+ if (stackTraceLineCount == 0 && STACK_TRACE_FIRST_LINE .matcher (line ).matches ()
703
+ || STACK_TRACE_OTHER_LINE .matcher (line ).matches ()) {
704
+ stackTraceLineCount ++;
705
+ } else {
706
+ stackTraceLineCount = 0 ;
682
707
}
683
708
684
709
// new error block?
@@ -714,21 +739,6 @@ static List<CompilerMessage> parseModernStream(int exitCode, BufferedReader inpu
714
739
}
715
740
}
716
741
717
- private static CompilerMessage parseAnnotationProcessorStream (final BufferedReader input ) throws IOException {
718
- String line = input .readLine ();
719
- final StringBuilder buffer = new StringBuilder ();
720
-
721
- while (line != null ) {
722
- if (!line .startsWith ("Consult the following stack trace for details." )) {
723
- buffer .append (line );
724
- buffer .append (EOL );
725
- }
726
- line = input .readLine ();
727
- }
728
-
729
- return new CompilerMessage (buffer .toString (), CompilerMessage .Kind .ERROR );
730
- }
731
-
732
742
private static boolean isMisc (String line ) {
733
743
return startsWithPrefix (line , MISC_PREFIXES );
734
744
}
0 commit comments