Skip to content

Commit c22f165

Browse files
adamvossolamy
authored andcommitted
Parse Javac warnings (#40)
* Improve parsing of warnings * Use a StringBuilder in parseModernError
1 parent cb56c30 commit c22f165

File tree

4 files changed

+183
-46
lines changed

4 files changed

+183
-46
lines changed

plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -669,14 +669,27 @@ static List<CompilerMessage> parseModernStream( int exitCode, BufferedReader inp
669669
{
670670
// javac output not detected by other parsing
671671
// maybe better to ignore only the summary an mark the rest as error
672-
if ( buffer.length() > 0 && ( buffer.toString().startsWith( "javac:" )
673-
|| buffer.toString().startsWith( "An exception has occurred in the compiler" ) ) )
672+
if (buffer.length() > 0 && buffer.toString().startsWith("javac:"))
674673
{
675674
errors.add( new CompilerMessage( buffer.toString(), CompilerMessage.Kind.ERROR ) );
676675
}
677676
return errors;
678677
}
679678

679+
// A compiler error occurred, treat everything that follows as part of the error.
680+
if (line.startsWith( "An exception has occurred in the compiler") ) {
681+
buffer = new StringBuilder();
682+
683+
while (line != null) {
684+
buffer.append(line);
685+
buffer.append(EOL);
686+
line = input.readLine();
687+
}
688+
689+
errors.add( new CompilerMessage( buffer.toString(), CompilerMessage.Kind.ERROR ) );
690+
return errors;
691+
}
692+
680693
// new error block?
681694
if ( !line.startsWith( " " ) && hasPointer )
682695
{
@@ -692,7 +705,11 @@ static List<CompilerMessage> parseModernStream( int exitCode, BufferedReader inp
692705
// TODO: there should be a better way to parse these
693706
if ( ( buffer.length() == 0 ) && line.startsWith( "error: " ) )
694707
{
695-
errors.add( new CompilerMessage( line, true ) );
708+
errors.add( new CompilerMessage( line, CompilerMessage.Kind.ERROR ) );
709+
}
710+
else if ( ( buffer.length() == 0 ) && line.startsWith( "warning: " ) )
711+
{
712+
errors.add( new CompilerMessage( line, CompilerMessage.Kind.WARNING ) );
696713
}
697714
else if ( ( buffer.length() == 0 ) && isNote( line ) )
698715
{
@@ -748,12 +765,10 @@ private static boolean startsWithPrefix( String line, String[] prefixes )
748765
*/
749766
static CompilerMessage parseModernError( int exitCode, String error )
750767
{
751-
StringTokenizer tokens = new StringTokenizer( error, ":" );
768+
final StringTokenizer tokens = new StringTokenizer( error, ":" );
752769

753770
boolean isError = exitCode != 0;
754771

755-
StringBuilder msgBuffer;
756-
757772
try
758773
{
759774
// With Java 6 error output lines from the compiler got longer. For backward compatibility
@@ -762,7 +777,7 @@ static CompilerMessage parseModernError( int exitCode, String error )
762777

763778
boolean tokenIsAnInteger;
764779

765-
String file = null;
780+
StringBuilder file = null;
766781

767782
String currentToken = null;
768783

@@ -772,11 +787,11 @@ static CompilerMessage parseModernError( int exitCode, String error )
772787
{
773788
if ( file == null )
774789
{
775-
file = currentToken;
790+
file = new StringBuilder(currentToken);
776791
}
777792
else
778793
{
779-
file = file + ':' + currentToken;
794+
file.append(':').append(currentToken);
780795
}
781796
}
782797

@@ -797,23 +812,23 @@ static CompilerMessage parseModernError( int exitCode, String error )
797812
}
798813
while ( !tokenIsAnInteger );
799814

800-
String lineIndicator = currentToken;
815+
final String lineIndicator = currentToken;
801816

802-
int startOfFileName = file.lastIndexOf( ']' );
817+
final int startOfFileName = file.toString().lastIndexOf( ']' );
803818

804819
if ( startOfFileName > -1 )
805820
{
806-
file = file.substring( startOfFileName + 1 + EOL.length() );
821+
file = new StringBuilder(file.substring(startOfFileName + 1 + EOL.length()));
807822
}
808823

809-
int line = Integer.parseInt( lineIndicator );
824+
final int line = Integer.parseInt( lineIndicator );
810825

811-
msgBuffer = new StringBuilder();
826+
final StringBuilder msgBuffer = new StringBuilder();
812827

813828
String msg = tokens.nextToken( EOL ).substring( 2 );
814829

815830
// Remove the 'warning: ' prefix
816-
String warnPrefix = getWarnPrefix( msg );
831+
final String warnPrefix = getWarnPrefix( msg );
817832
if ( warnPrefix != null )
818833
{
819834
isError = false;
@@ -834,7 +849,7 @@ static CompilerMessage parseModernError( int exitCode, String error )
834849

835850
do
836851
{
837-
String msgLine = tokens.nextToken( EOL );
852+
final String msgLine = tokens.nextToken( EOL );
838853

839854
if ( pointer != null )
840855
{
@@ -859,18 +874,18 @@ else if ( msgLine.endsWith( "^" ) )
859874

860875
msgBuffer.append( EOL );
861876

862-
String message = msgBuffer.toString();
877+
final String message = msgBuffer.toString();
863878

864-
int startcolumn = pointer.indexOf( "^" );
879+
final int startcolumn = pointer.indexOf( "^" );
865880

866-
int endcolumn = context == null ? startcolumn : context.indexOf( " ", startcolumn );
881+
int endcolumn = (context == null) ? startcolumn : context.indexOf(" ", startcolumn);
867882

868883
if ( endcolumn == -1 )
869884
{
870885
endcolumn = context.length();
871886
}
872887

873-
return new CompilerMessage( file, isError, line, startcolumn, line, endcolumn, message.trim() );
888+
return new CompilerMessage(file.toString(), isError, line, startcolumn, line, endcolumn, message.trim() );
874889
}
875890
catch ( NoSuchElementException e )
876891
{

plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/AbstractJavacCompilerTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ protected int expectedErrors()
7474

7575
protected int expectedWarnings()
7676
{
77+
if (getJavaVersion().contains("1.8")){
78+
// lots of new warnings about obsoletions for future releases
79+
return 30;
80+
}
81+
82+
if ( "1.6".compareTo( getJavaVersion() ) < 0 )
83+
{
84+
// with 1.7 some warning with bootstrap class path not set in conjunction with -source 1.3
85+
return 9;
86+
}
87+
7788
return 2;
7889
}
7990

plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/ErrorMessageParserTest.java

Lines changed: 137 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -623,14 +623,17 @@ public void testCRLF_windows()
623623
"4 warnings" + CRLF;
624624
List<CompilerMessage> compilerMessages =
625625
JavacCompiler.parseModernStream( 0, new BufferedReader( new StringReader( errors ) ) );
626-
assertEquals( "count", 107, compilerMessages.size() );
626+
assertEquals( "count", 187, compilerMessages.size() );
627627
List<CompilerMessage> compilerErrors = new ArrayList<CompilerMessage>( 3 );
628628
for ( CompilerMessage message : compilerMessages ) {
629629
if ( message.getKind() != CompilerMessage.Kind.OTHER ) {
630630
compilerErrors.add( message );
631631
}
632632
}
633-
CompilerMessage error1 = compilerErrors.get( 0 );
633+
634+
assertEquivalent(new CompilerMessage("[options] bootstrap class path not set in conjunction with -source " +
635+
"1.6", CompilerMessage.Kind.WARNING), compilerErrors.get(0));
636+
CompilerMessage error1 = compilerErrors.get( 1 );
634637
assertEquals( "file",
635638
"C:\\commander\\pre\\ec\\ec-http\\src\\main\\java\\com\\electriccloud\\http\\HttpUtil.java",
636639
error1.getFile() );
@@ -639,7 +642,7 @@ public void testCRLF_windows()
639642
error1.getMessage() );
640643
assertEquals( "line", 31, error1.getStartLine() );
641644
assertEquals( "column", 38, error1.getStartColumn() );
642-
CompilerMessage error2 = compilerErrors.get( 1 );
645+
CompilerMessage error2 = compilerErrors.get( 2 );
643646
assertEquals( "file",
644647
"C:\\commander\\pre\\ec\\ec-http\\src\\main\\java\\com\\electriccloud\\http\\HttpUtil.java",
645648
error2.getFile() );
@@ -648,7 +651,7 @@ public void testCRLF_windows()
648651
error2.getMessage() );
649652
assertEquals( "line", 151, error2.getStartLine() );
650653
assertEquals( "column", 8, error2.getStartColumn() );
651-
CompilerMessage error3 = compilerErrors.get( 2 );
654+
CompilerMessage error3 = compilerErrors.get( 3 );
652655
assertEquals( "file",
653656
"C:\\commander\\pre\\ec\\ec-http\\src\\main\\java\\com\\electriccloud\\http\\HttpUtil.java",
654657
error3.getFile() );
@@ -681,7 +684,7 @@ public void testJava6Error() throws Exception
681684

682685
assertTrue( message1.isError() );
683686

684-
assertEquals( "cannot find symbol" + EOL +
687+
assertEquals( "cannot find symbol" + EOL +
685688
"symbol : class Properties" + EOL +
686689
"location: class Error", message1.getMessage() );
687690

@@ -697,7 +700,7 @@ public void testJava6Error() throws Exception
697700

698701
assertTrue( message2.isError() );
699702

700-
assertEquals( "cannot find symbol" + EOL +
703+
assertEquals( "cannot find symbol" + EOL +
701704
"symbol : class Properties" + EOL +
702705
"location: class Error", message2.getMessage() );
703706

@@ -732,7 +735,7 @@ public void testJava7Error() throws Exception
732735

733736
assertTrue( message1.isError() );
734737

735-
assertEquals( "error: cannot find symbol" + EOL +
738+
assertEquals( "error: cannot find symbol" + EOL +
736739
" symbol: class Properties" + EOL +
737740
" location: class Error", message1.getMessage() );
738741

@@ -748,7 +751,7 @@ public void testJava7Error() throws Exception
748751

749752
assertTrue( message2.isError() );
750753

751-
assertEquals( "error: cannot find symbol" + EOL +
754+
assertEquals( "error: cannot find symbol" + EOL +
752755
" symbol: class Properties" + EOL +
753756
" location: class Error", message2.getMessage() );
754757

@@ -774,5 +777,130 @@ public void testBugParade() throws Exception
774777

775778
assertEquals( 1, compilerErrors.size() );
776779
}
777-
780+
781+
public final void testNonAnchoredWarning() throws IOException {
782+
final String error =
783+
"warning: [options] bootstrap class path not set in conjunction with -source 1.6" + EOL +
784+
"1 warning" + EOL;
785+
786+
final List<CompilerMessage> compilerErrors = JavacCompiler.parseModernStream(0, new BufferedReader(new
787+
StringReader(
788+
error)));
789+
790+
assertNotNull(compilerErrors);
791+
assertEquals(1, compilerErrors.size());
792+
assertEquivalent(
793+
new CompilerMessage(
794+
"[options] bootstrap class path not set in conjunction with -source 1.6", CompilerMessage.Kind.WARNING),
795+
compilerErrors.get(0));
796+
}
797+
798+
public final void testAnchoredWarning() throws IOException {
799+
final String error =
800+
"C:\\repo\\src\\it\\includes-output-when-compiler-forked\\src\\main" +
801+
"\\java\\MyClass.java:23: warning: [divzero] division by zero" + EOL +
802+
" System.out.println(1/0);" + EOL +
803+
" ^" + EOL +
804+
"1 warnings" + EOL;
805+
806+
final List<CompilerMessage> compilerErrors =
807+
JavacCompiler.parseModernStream(0, new BufferedReader(new StringReader(error)));
808+
809+
assertNotNull(compilerErrors);
810+
assertEquals(1, compilerErrors.size());
811+
assertEquivalent(
812+
new CompilerMessage("C:\\repo\\src\\it\\includes-output-when-compiler-forked\\src\\main\\java\\MyClass" +
813+
".java", CompilerMessage.Kind.WARNING, 23, 27, 23, 30, "[divzero] division by zero"),
814+
compilerErrors.get(0));
815+
}
816+
817+
public final void testMixedWarnings() throws IOException {
818+
final String error =
819+
"warning: [options] bootstrap class path not set in conjunction with -source 1.6" + EOL +
820+
"C:\\repo\\src\\it\\includes-output-when-compiler-forked\\src\\main\\java" +
821+
"\\MyClass.java:23: warning: [divzero] division by zero" + EOL +
822+
" System.out.println(1/0);" + EOL +
823+
" ^" + EOL +
824+
"2 warnings";
825+
826+
final List<CompilerMessage> compilerErrors =
827+
JavacCompiler.parseModernStream(0, new BufferedReader(new StringReader(error)));
828+
829+
assertNotNull(compilerErrors);
830+
assertEquals(2, compilerErrors.size());
831+
assertEquivalent(
832+
new CompilerMessage(
833+
"[options] bootstrap class path not set in conjunction with -source 1.6", CompilerMessage.Kind.WARNING),
834+
compilerErrors.get(0));
835+
assertEquivalent(
836+
new CompilerMessage("C:\\repo\\src\\it\\includes-output-when-compiler-forked\\src\\main\\java\\MyClass" +
837+
".java", CompilerMessage.Kind.WARNING, 23, 27, 23, 30, "[divzero] division by zero"),
838+
compilerErrors.get(1));
839+
}
840+
841+
public final void testIssue37() throws IOException {
842+
final String error =
843+
"warning: [path] bad path element \"d:\\maven_repo\\.m2\\repository\\org\\ow2\\asm\\asm-xml\\5.0.3\\asm-5.0.3.jar\": no such file or directory" + EOL +
844+
"warning: [path] bad path element \"d:\\maven_repo\\.m2\\repository\\org\\ow2\\asm\\asm-xml\\5.0.3\\asm-util-5.0.3.jar\": no such file or directory" + EOL +
845+
"warning: [options] bootstrap class path not set in conjunction with -source 1.7" + EOL +
846+
"3 warnings" + EOL +
847+
"An exception has occurred in the compiler (9). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you." + EOL +
848+
"java.lang.NullPointerException" + EOL +
849+
"\tat jdk.zipfs/jdk.nio.zipfs.JarFileSystem.getVersionMap(JarFileSystem.java:137)" + EOL +
850+
"\tat jdk.zipfs/jdk.nio.zipfs.JarFileSystem.createVersionedLinks(JarFileSystem.java:112)" + EOL +
851+
"\tat jdk.zipfs/jdk.nio.zipfs.JarFileSystem.<init>(JarFileSystem.java:85)" + EOL +
852+
"\tat jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:134)" + EOL +
853+
"\tat jdk.compiler/com.sun.tools.javac.file.JavacFileManager$ArchiveContainer.<init>(JavacFileManager.java:517)" + EOL +
854+
"\tat jdk.compiler/com.sun.tools.javac.file.JavacFileManager.getContainer(JavacFileManager.java:319)" + EOL +
855+
"\tat jdk.compiler/com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:715)" + EOL +
856+
"\tat jdk.compiler/com.sun.tools.javac.code.ClassFinder.list(ClassFinder.java:722)" + EOL +
857+
"\tat jdk.compiler/com.sun.tools.javac.code.ClassFinder.scanUserPaths(ClassFinder.java:655)" + EOL +
858+
"\tat jdk.compiler/com.sun.tools.javac.code.ClassFinder.fillIn(ClassFinder.java:526)" + EOL +
859+
"\tat jdk.compiler/com.sun.tools.javac.code.ClassFinder.complete(ClassFinder.java:293)" + EOL +
860+
"\tat jdk.compiler/com.sun.tools.javac.code.Symbol.complete(Symbol.java:633)" + EOL +
861+
"\tat jdk.compiler/com.sun.tools.javac.code.Symbol$PackageSymbol.members(Symbol.java:1120)" + EOL +
862+
"\tat jdk.compiler/com.sun.tools.javac.code.Symtab.listPackageModules(Symtab.java:810)" + EOL +
863+
"\tat jdk.compiler/com.sun.tools.javac.comp.Enter.visitTopLevel(Enter.java:344)" + EOL +
864+
"\tat jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:529)" + EOL +
865+
"\tat jdk.compiler/com.sun.tools.javac.comp.Enter.classEnter(Enter.java:285)" + EOL +
866+
"\tat jdk.compiler/com.sun.tools.javac.comp.Enter.classEnter(Enter.java:300)" + EOL +
867+
"\tat jdk.compiler/com.sun.tools.javac.comp.Enter.complete(Enter.java:570)" + EOL +
868+
"\tat jdk.compiler/com.sun.tools.javac.comp.Enter.main(Enter.java:554)" + EOL +
869+
"\tat jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1052)" + EOL +
870+
"\tat jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:923)" + EOL +
871+
"\tat jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:302)" + EOL +
872+
"\tat jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:162)" + EOL +
873+
"\tat jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:57)" + EOL +
874+
"\tat jdk.compiler/com.sun.tools.javac.Main.main(Main.java:43)";
875+
876+
final List<CompilerMessage> compilerErrors =
877+
JavacCompiler.parseModernStream(0, new BufferedReader(new StringReader(error)));
878+
879+
assertNotNull( compilerErrors );
880+
assertEquals(4, compilerErrors.size());
881+
882+
assertEquivalent(new CompilerMessage("[path] bad path element \"d:\\maven_repo\\" +
883+
".m2\\repository\\org\\ow2\\asm\\asm-xml\\5.0.3\\asm-5.0.3.jar\": no such file or directory",
884+
CompilerMessage.Kind.WARNING), compilerErrors.get(0));
885+
assertEquivalent(new CompilerMessage("warning: [path] bad path element \"d:\\maven_repo\\.m2\\repository\\org\\ow2\\asm\\asm-xml\\5.0.3\\asm-util-5.0.3.jar\": no such file or directory",
886+
CompilerMessage.Kind.WARNING), compilerErrors.get(1));
887+
assertEquivalent(new CompilerMessage("[options] bootstrap class path not set in conjunction with -source 1.7",
888+
CompilerMessage.Kind.WARNING), compilerErrors.get(2));
889+
890+
final CompilerMessage finalMessage = compilerErrors.get(3);
891+
assertEquals(CompilerMessage.Kind.ERROR, finalMessage.getKind());
892+
assertTrue("Starts correctly", finalMessage.getMessage().startsWith("An exception has occurred in the compiler"));
893+
assertTrue("continues through end of output", finalMessage.getMessage().endsWith("\tat jdk.compiler/com.sun" +
894+
".tools.javac.Main.main(Main.java:43)" + EOL));
895+
}
896+
897+
private static void assertEquivalent(CompilerMessage expected, CompilerMessage actual){
898+
assertEquals("Message did not match", expected.getMessage(), actual.getMessage());
899+
assertEquals("Kind did not match", expected.getKind(), actual.getKind());
900+
assertEquals("File did not match", expected.getFile(), actual.getFile());
901+
assertEquals( "Start line did not match", expected.getStartLine(), actual.getStartLine());
902+
assertEquals( "Start column did not match", expected.getStartColumn(), actual.getStartColumn());
903+
assertEquals("End line did not match", expected.getEndLine(), actual.getEndLine());
904+
assertEquals("End column did not match", expected.getEndColumn(), actual.getEndColumn());
905+
}
778906
}

plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/JavaxToolsCompilerTest.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,4 @@ public class JavaxToolsCompilerTest
2525
extends AbstractJavacCompilerTest
2626
{
2727
// no op default is to javax.tools if available
28-
29-
protected int expectedWarnings()
30-
{
31-
if (getJavaVersion().contains("1.8")){
32-
// lots of new warnings about obsoletions for future releases
33-
return 30;
34-
}
35-
else if ( "1.6".compareTo( getJavaVersion() ) < 0 )
36-
{
37-
// with 1.7 some warning with bootstrap class path not set in conjunction with -source 1.3
38-
return 9;
39-
}
40-
else
41-
{
42-
return 2;
43-
}
44-
}
4528
}

0 commit comments

Comments
 (0)