Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
authorDusan Balek <dbalek@netbeans.org>
Mon, 31 Jul 2017 11:07:41 +0200
changeset 5955f54cccaf6e6c
parent 5954 f453b3a76796
child 5956 15c0d1682895
Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java
src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java
src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
test/tools/javac/modules/EdgeCases.java
     1.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Mon Jun 26 10:38:22 2017 +0200
     1.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Mon Jul 31 11:07:41 2017 +0200
     1.3 @@ -355,6 +355,8 @@
     1.4          JavaFileObject classfile = c.classfile;
     1.5          if (classfile != null) {
     1.6              JavaFileObject previousClassFile = currentClassFile;
     1.7 +            Symbol prevOwner = c.owner;
     1.8 +            Name prevName = c.fullname;
     1.9              try {
    1.10                  if (reader.filling) {
    1.11                      Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
    1.12 @@ -377,6 +379,21 @@
    1.13                                                          + classfile.toUri());
    1.14                      }
    1.15                  }
    1.16 +            } catch (BadClassFile cf) {
    1.17 +                //the symbol may be partially initialized, purge it:
    1.18 +                c.owner = prevOwner;
    1.19 +                c.members_field.getSymbols(sym -> sym.kind == TYP).forEach(sym -> {
    1.20 +                    ClassSymbol csym = (ClassSymbol) sym;
    1.21 +                    csym.owner = sym.packge();
    1.22 +                    csym.owner.members().enter(sym);
    1.23 +                    csym.fullname = sym.flatName();
    1.24 +                    csym.name = Convert.shortName(sym.flatName());
    1.25 +                    csym.reset();
    1.26 +                });
    1.27 +                c.fullname = prevName;
    1.28 +                c.name = Convert.shortName(prevName);
    1.29 +                c.reset();
    1.30 +                throw cf;
    1.31              } finally {
    1.32                  currentClassFile = previousClassFile;
    1.33              }
     2.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Mon Jun 26 10:38:22 2017 +0200
     2.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Mon Jul 31 11:07:41 2017 +0200
     2.3 @@ -31,7 +31,6 @@
     2.4  import java.util.Map;
     2.5  import java.util.NoSuchElementException;
     2.6  import java.util.Set;
     2.7 -import java.util.function.Function;
     2.8  
     2.9  import javax.tools.JavaFileManager;
    2.10  import javax.tools.JavaFileManager.Location;
    2.11 @@ -58,6 +57,7 @@
    2.12  import com.sun.tools.javac.util.Names;
    2.13  
    2.14  import static com.sun.tools.javac.code.Kinds.Kind.*;
    2.15 +import com.sun.tools.javac.comp.Check;
    2.16  
    2.17  /**
    2.18   *  This class provides operations to locate module definitions
    2.19 @@ -82,6 +82,7 @@
    2.20      private final Names names;
    2.21  
    2.22      private final ClassFinder classFinder;
    2.23 +    private final Check chk;
    2.24  
    2.25      /** Access to files
    2.26       */
    2.27 @@ -109,6 +110,7 @@
    2.28          fileManager = context.get(JavaFileManager.class);
    2.29          log = Log.instance(context);
    2.30          classFinder = ClassFinder.instance(context);
    2.31 +        chk = Check.instance(context);
    2.32  
    2.33          diags = JCDiagnostic.Factory.instance(context);
    2.34      }
    2.35 @@ -203,7 +205,13 @@
    2.36              if (fo == null) {
    2.37                  msym = syms.unnamedModule;
    2.38              } else {
    2.39 -                msym = readModule(fo);
    2.40 +                try {
    2.41 +                    msym = readModule(fo);
    2.42 +                } catch (CompletionFailure ex) {
    2.43 +                    chk.completionError(null, ex);
    2.44 +                    msym = syms.unnamedModule;
    2.45 +                }
    2.46 +                    
    2.47              }
    2.48  
    2.49              if (msym.patchLocation == null) {
     3.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jun 26 10:38:22 2017 +0200
     3.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jul 31 11:07:41 2017 +0200
     3.3 @@ -290,8 +290,7 @@
     3.4       */
     3.5      public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
     3.6          log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
     3.7 -        if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
     3.8 -        else return syms.errType;
     3.9 +        return syms.errType;
    3.10      }
    3.11  
    3.12      /** Report an error that wrong type tag was found.
     4.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Jun 26 10:38:22 2017 +0200
     4.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Jul 31 11:07:41 2017 +0200
     4.3 @@ -94,10 +94,8 @@
     4.4  import com.sun.tools.javac.tree.JCTree.JCUses;
     4.5  import com.sun.tools.javac.tree.JCTree.Tag;
     4.6  import com.sun.tools.javac.tree.TreeInfo;
     4.7 -import com.sun.tools.javac.util.Abort;
     4.8  import com.sun.tools.javac.util.Assert;
     4.9  import com.sun.tools.javac.util.Context;
    4.10 -import com.sun.tools.javac.util.JCDiagnostic;
    4.11  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    4.12  import com.sun.tools.javac.util.List;
    4.13  import com.sun.tools.javac.util.ListBuffer;
    4.14 @@ -105,7 +103,6 @@
    4.15  import com.sun.tools.javac.util.Name;
    4.16  import com.sun.tools.javac.util.Names;
    4.17  import com.sun.tools.javac.util.Options;
    4.18 -import com.sun.tools.javac.util.Position;
    4.19  
    4.20  import static com.sun.tools.javac.code.Flags.ABSTRACT;
    4.21  import static com.sun.tools.javac.code.Flags.ENUM;
    4.22 @@ -293,8 +290,7 @@
    4.23                  msym.complete();
    4.24              }
    4.25          } catch (CompletionFailure ex) {
    4.26 -            log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, Position.NOPOS, "cant.access", ex.sym, ex.getDetailValue());
    4.27 -            if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
    4.28 +            chk.completionError(null, ex);
    4.29          } finally {
    4.30              depth--;
    4.31          }
    4.32 @@ -1283,10 +1279,6 @@
    4.33          Predicate<ModuleSymbol> observablePred = sym ->
    4.34               (observable == null) ? (moduleFinder.findModule(sym).kind != ERR) : observable.contains(sym);
    4.35          Predicate<ModuleSymbol> systemModulePred = sym -> (sym.flags() & Flags.SYSTEM_MODULE) != 0;
    4.36 -        Predicate<ModuleSymbol> noIncubatorPred = sym -> {
    4.37 -            sym.complete();
    4.38 -            return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
    4.39 -        };
    4.40          Set<ModuleSymbol> enabledRoot = new LinkedHashSet<>();
    4.41  
    4.42          if (rootModules.contains(syms.unnamedModule)) {
    4.43 @@ -1304,9 +1296,18 @@
    4.44                  jdkModulePred = sym -> true;
    4.45              }
    4.46  
    4.47 +            Predicate<ModuleSymbol> noIncubatorPred = sym -> {
    4.48 +                sym.complete();
    4.49 +                return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
    4.50 +            };
    4.51 +
    4.52              for (ModuleSymbol sym : new HashSet<>(syms.getAllModules())) {
    4.53 -                if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
    4.54 -                    enabledRoot.add(sym);
    4.55 +                try {
    4.56 +                    if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
    4.57 +                        enabledRoot.add(sym);
    4.58 +                    }
    4.59 +                } catch (CompletionFailure ex) {
    4.60 +                    chk.completionError(null, ex);
    4.61                  }
    4.62              }
    4.63          }
    4.64 @@ -1398,32 +1399,36 @@
    4.65          result.add(syms.java_base);
    4.66  
    4.67          while (primaryTodo.nonEmpty() || secondaryTodo.nonEmpty()) {
    4.68 -            ModuleSymbol current;
    4.69 -            boolean isPrimaryTodo;
    4.70 -            if (primaryTodo.nonEmpty()) {
    4.71 -                current = primaryTodo.head;
    4.72 -                primaryTodo = primaryTodo.tail;
    4.73 -                isPrimaryTodo = true;
    4.74 -            } else {
    4.75 -                current = secondaryTodo.head;
    4.76 -                secondaryTodo = secondaryTodo.tail;
    4.77 -                isPrimaryTodo = false;
    4.78 -            }
    4.79 -            if (observable != null && !observable.contains(current))
    4.80 -                continue;
    4.81 -            if (!result.add(current) || current == syms.unnamedModule || ((current.flags_field & Flags.AUTOMATIC_MODULE) != 0))
    4.82 -                continue;
    4.83 -            current.complete();
    4.84 -            if (current.kind == ERR && isPrimaryTodo && warnedMissing.add(current)) {
    4.85 -                log.error(Errors.ModuleNotFound(current));
    4.86 -            }
    4.87 -            for (RequiresDirective rd : current.requires) {
    4.88 -                if (rd.module == syms.java_base) continue;
    4.89 -                if ((rd.isTransitive() && isPrimaryTodo) || base.contains(current)) {
    4.90 -                    primaryTodo = primaryTodo.prepend(rd.module);
    4.91 +            try {
    4.92 +                ModuleSymbol current;
    4.93 +                boolean isPrimaryTodo;
    4.94 +                if (primaryTodo.nonEmpty()) {
    4.95 +                    current = primaryTodo.head;
    4.96 +                    primaryTodo = primaryTodo.tail;
    4.97 +                    isPrimaryTodo = true;
    4.98                  } else {
    4.99 -                    secondaryTodo = secondaryTodo.prepend(rd.module);
   4.100 +                    current = secondaryTodo.head;
   4.101 +                    secondaryTodo = secondaryTodo.tail;
   4.102 +                    isPrimaryTodo = false;
   4.103                  }
   4.104 +                if (observable != null && !observable.contains(current))
   4.105 +                    continue;
   4.106 +                if (!result.add(current) || current == syms.unnamedModule || ((current.flags_field & Flags.AUTOMATIC_MODULE) != 0))
   4.107 +                    continue;
   4.108 +                current.complete();
   4.109 +                if (current.kind == ERR && isPrimaryTodo && warnedMissing.add(current)) {
   4.110 +                    log.error(Errors.ModuleNotFound(current));
   4.111 +                }
   4.112 +                for (RequiresDirective rd : current.requires) {
   4.113 +                    if (rd.module == syms.java_base) continue;
   4.114 +                    if ((rd.isTransitive() && isPrimaryTodo) || base.contains(current)) {
   4.115 +                        primaryTodo = primaryTodo.prepend(rd.module);
   4.116 +                    } else {
   4.117 +                        secondaryTodo = secondaryTodo.prepend(rd.module);
   4.118 +                    }
   4.119 +                }
   4.120 +            } catch (CompletionFailure ex) {
   4.121 +                chk.completionError(null, ex);
   4.122              }
   4.123          }
   4.124  
     5.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Jun 26 10:38:22 2017 +0200
     5.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Jul 31 11:07:41 2017 +0200
     5.3 @@ -1435,7 +1435,7 @@
     5.4          ClassSymbol c = readClassSymbol(nextChar());
     5.5          NameAndType nt = readNameAndType(nextChar());
     5.6  
     5.7 -        if (c.members_field == null)
     5.8 +        if (c.members_field == null || c.kind != TYP)
     5.9              throw badClassFile("bad.enclosing.class", self, c);
    5.10  
    5.11          MethodSymbol m = findMethod(nt, c.members_field, self.flags());
     6.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Jun 26 10:38:22 2017 +0200
     6.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Jul 31 11:07:41 2017 +0200
     6.3 @@ -408,8 +408,6 @@
     6.4          } catch (CompletionFailure ex) {
     6.5              // inlined Check.completionError as it is not initialized yet
     6.6              log.error("cant.access", ex.sym, ex.getDetailValue());
     6.7 -            if (ex instanceof ClassFinder.BadClassFile)
     6.8 -                throw new Abort();
     6.9          }
    6.10          source = Source.instance(context);
    6.11          attr = Attr.instance(context);
     7.1 --- a/test/tools/javac/modules/EdgeCases.java	Mon Jun 26 10:38:22 2017 +0200
     7.2 +++ b/test/tools/javac/modules/EdgeCases.java	Mon Jul 31 11:07:41 2017 +0200
     7.3 @@ -467,7 +467,8 @@
     7.4  
     7.5          List<String> expected = Arrays.asList(
     7.6                  "- compiler.err.cant.access: m1x.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.module.name.mismatch: other, m1x))",
     7.7 -                "1 error");
     7.8 +                "module-info.java:1:1: compiler.err.module.not.found: m1x",
     7.9 +                "2 errors");
    7.10  
    7.11          if (!expected.equals(log)) {
    7.12              throw new AssertionError("Unexpected output: " + log);