Skip to content

Stop using the CompilerClassLoader in sbt-bridge #10960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion community-build/community-projects/PPrint
Submodule PPrint updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/fansi
Submodule fansi updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/geny
Submodule geny updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/os-lib
Submodule os-lib updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/requests-scala
Submodule requests-scala updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/scas
Submodule scas updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/sourcecode
Submodule sourcecode updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/upickle
Submodule upickle updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion community-build/community-projects/utest
Submodule utest updated 1 files
+1 −1 mill
2 changes: 1 addition & 1 deletion sbt-bridge/src/xsbt/CompilerClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@ private static ClassLoader computeFixedLoader(ClassLoader bridgeLoader) {
throw new RuntimeException(e);
}
}
}
}
48 changes: 31 additions & 17 deletions sbt-bridge/src/xsbt/CompilerInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,50 @@
import xsbti.AnalysisCallback;
import xsbti.Logger;
import xsbti.Reporter;
import xsbti.Severity;
import xsbti.compile.*;

import java.io.File;

import dotty.tools.dotc.core.Contexts.ContextBase;
import dotty.tools.dotc.Main;
import dotty.tools.dotc.interfaces.*;

import java.lang.reflect.InvocationTargetException;
import java.net.URLClassLoader;
import java.io.File;

/**
* The new compiler interface is [[dotty.tools.xsbt.CompilerBridge]] that extends the new `xsbti.CompilerInterface2`.
* This interface is kept for compatibility with Mill and the sbt 1.3.x series.
*/
public final class CompilerInterface {
public CachedCompiler newCompiler(String[] options, Output output, Logger initialLog, Reporter initialDelegate) {
// The classloader that sbt uses to load the compiler bridge is broken
// (see CompilerClassLoader#fixBridgeLoader for details). To workaround
// this we construct our own ClassLoader and then run the following code
// with it:
// new CachedCompilerImpl(options, output)
public CachedCompiler newCompiler(String[] options, Output output, Logger initialLog, Reporter initialDelegate) throws java.lang.Exception {
if(isClassLoaderValid()) {
return new CachedCompilerImpl(options, output);
} else {
initialLog.warn(() ->
"The compiler class loader is badly configured.\n" +
"Consider using a more recent version of your build tool:\n" +
" - sbt >= 1.4.0 and sbt-dotty >= 1.5.0\n" +
" - Mill >= 0.9.3-21-002361\n" +
" - Bloop >= 1.4.6-23-20a501bc"
);
// To workaround the wrong class loader, we construct our own and run
// the following code with it:
// new CachedCompilerImpl(options, output)
try {
ClassLoader bridgeLoader = this.getClass().getClassLoader();
ClassLoader fixedLoader = CompilerClassLoader.fixBridgeLoader(bridgeLoader);
Class<?> cciClass = fixedLoader.loadClass("xsbt.CachedCompilerImpl");
return (CachedCompiler) cciClass.getConstructors()[0].newInstance(options, output);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}

private boolean isClassLoaderValid() {
// Check that the `xsbti.*` classes are loaded from the same class loader in the compiler and the bridge
ClassLoader compilerClassLoader = Main.class.getClassLoader();
Class<Logger> clazz = Logger.class;
try {
ClassLoader bridgeLoader = this.getClass().getClassLoader();
ClassLoader fixedLoader = CompilerClassLoader.fixBridgeLoader(bridgeLoader);
Class<?> cciClass = fixedLoader.loadClass("xsbt.CachedCompilerImpl");
return (CachedCompiler) cciClass.getConstructors()[0].newInstance(options, output);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
return compilerClassLoader.loadClass("xsbti.Logger") == clazz;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
Expand Down