Suggested patch for javac bug

Andrew Haley aph at redhat.com
Mon Jan 24 10:45:10 PST 2011


When an enumeration implements an interface, and the .class file for
that interface is absent, javac throws an exception.  This sounds
rather like a weird corner case, but we saw it when trying to build
NetBeans.

Like so:

  $ /local/jdk7/build/linux-amd64/j2sdk-image/bin/javac Conc.java
  $ rm Interf.*
  $ /local/jdk7/build/linux-amd64/j2sdk-image/bin/javac Conc.java
An exception has occurred in the compiler (1.7.0-internal). 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.
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for Interf not found

I've been looking at this, and it's not easy to fix.  The problem is
that Resolve.findMethod() calls Type.flags() on the missing interface,
and ClassReader throws a CompletionFailure that no-one is ready to
catch.

If we catch the exception in Resolve.findMethod(), we can log an error
and return typeNotFound.  Like this, perhaps:

diff -r 27f03394a69d src/share/classes/com/sun/tools/javac/comp/Resolve.java
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jun 23 16:44:15 2010 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Jan 24 17:41:05 2011 +0000
@@ -735,8 +735,13 @@
                                boolean operator) {
          for (Type ct = intype; ct.tag == CLASS; ct = types.supertype(ct)) {
              ClassSymbol c = (ClassSymbol)ct.tsym;
-            if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
-                abstractok = false;
+            try {
+                if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
+            	     abstractok = false;
+            } catch (CompletionFailure ex) {
+                log.error("cant.access", ex.sym, ex.errmsg);
+            	return typeNotFound;
+            }
              for (Scope.Entry e = c.members().lookup(name);
                   e.scope != null;
                   e = e.next()) {

This is an improvement, but does not give a good error message because
we don't have a DiagnosticPosition, so we can't give a line number.
We just get this:

error: cannot access Interf
class file for Interf not found
1 error

We could simply return typeNotFound, rather than logging the error,
but this causes the compilation silently to succeed, and I think we
need an error message.

I can't figure out any nice way to fix this.  Any suggestions?

Thanks,
Andrew.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Interf.java
Type: text/x-java
Size: 47 bytes
Desc: not available
Url : http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20110124/0cbcad28/Interf.java 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Conc.java
Type: text/x-java
Size: 158 bytes
Desc: not available
Url : http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20110124/0cbcad28/Conc.java 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Enumeration.java
Type: text/x-java
Size: 58 bytes
Desc: not available
Url : http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20110124/0cbcad28/Enumeration.java 


More information about the compiler-dev mailing list