# HG changeset patch # User vromero # Date 1488415128 28800 # Node ID 6ebcb2cb95071ed5f01bd343f595ebde06a7a065 # Parent 4a79ad46e578112fce68f1af9dd931025cc235cb 8167638: javac can improve the error message issued when IllegalAccessError is produced Reviewed-by: jjg diff -r 4a79ad46e578 -r 6ebcb2cb9507 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Jul 05 22:55:08 2017 +0200 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Mar 01 16:38:48 2017 -0800 @@ -31,10 +31,13 @@ import java.io.PrintWriter; import java.net.URL; import java.nio.file.NoSuchFileException; +import java.security.CodeSource; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.tools.JavaFileManager; @@ -325,6 +328,11 @@ } catch (PropagatedException ex) { // TODO: what about errors from plugins? should not simply rethrow the error here throw ex.getCause(); + } catch (IllegalAccessError iae) { + if (twoClassLoadersInUse(iae)) { + bugMessage(iae); + } + return Result.ABNORMAL; } catch (Throwable ex) { // Nasty. If we've already reported an error, compensate // for buggy compiler error recovery by swallowing thrown @@ -343,6 +351,35 @@ } } + private boolean twoClassLoadersInUse(IllegalAccessError iae) { + String msg = iae.getMessage(); + Pattern pattern = Pattern.compile("(?i)(?<=tried to access class )([a-z_$][a-z\\d_$]*\\.)*[a-z_$][a-z\\d_$]*"); + Matcher matcher = pattern.matcher(msg); + if (matcher.find()) { + try { + String otherClassName = matcher.group(0); + Class otherClass = Class.forName(otherClassName); + ClassLoader otherClassLoader = otherClass.getClassLoader(); + ClassLoader javacClassLoader = this.getClass().getClassLoader(); + if (javacClassLoader != otherClassLoader) { + CodeSource otherClassCodeSource = otherClass.getProtectionDomain().getCodeSource(); + CodeSource javacCodeSource = this.getClass().getProtectionDomain().getCodeSource(); + if (otherClassCodeSource != null && javacCodeSource != null) { + log.printLines(PrefixKind.JAVAC, "err.two.class.loaders.2", + otherClassCodeSource.getLocation(), + javacCodeSource.getLocation()); + } else { + log.printLines(PrefixKind.JAVAC, "err.two.class.loaders.1"); + } + return true; + } + } catch (Throwable t) { + return false; + } + } + return false; + } + /** Print a message reporting an internal error. */ void bugMessage(Throwable ex) { diff -r 4a79ad46e578 -r 6ebcb2cb9507 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Wed Jul 05 22:55:08 2017 +0200 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Wed Mar 01 16:38:48 2017 -0800 @@ -370,6 +370,12 @@ not a file: {0} javac.err.cannot.access.runtime.env=\ cannot access runtime environment +javac.err.two.class.loaders.1=\ + javac is split between multiple class loaders: check your configuration +javac.err.two.class.loaders.2=\ + javac is split between multiple class loaders:\n\ + one class comes from file: {0}\n\ + while javac comes from {1} javac.err.bad.value.for.option=\ bad value for {0} option: ''{1}'' javac.err.no.value.for.option=\