mirror of https://github.com/sbt/sbt.git
Fix actions/completions
When loading a scripted test, sbt creates a jar file and loads it. The path of the jar file is the same for all the batched tests. We must prevent the JDK from caching this jar file to force a reload after each test. Otherwise sbt tries to load the auto-plugins of a previous test and fails.
This commit is contained in:
parent
52fd2b4427
commit
b0f3cb0a8e
|
|
@ -8,10 +8,14 @@
|
|||
package sbt.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.file.Paths;
|
||||
import xsbti.*;
|
||||
|
||||
/**
|
||||
|
|
@ -25,6 +29,10 @@ public class XMainConfiguration {
|
|||
public xsbti.MainResult run(String moduleName, xsbti.AppConfiguration configuration)
|
||||
throws Throwable {
|
||||
try {
|
||||
boolean isScripted = Boolean.parseBoolean(System.getProperty("sbt.scripted"));
|
||||
// in batch scripted tests, we disable caching of JAR URL connections to avoid interference
|
||||
// between tests
|
||||
if (isScripted) disableCachingOfURLConnections();
|
||||
ClassLoader topLoader = configuration.provider().scalaProvider().launcher().topLoader();
|
||||
xsbti.AppConfiguration updatedConfiguration = null;
|
||||
try {
|
||||
|
|
@ -56,7 +64,7 @@ public class XMainConfiguration {
|
|||
clw.getMethod("warmup").invoke(clw.getField("MODULE$").get(null));
|
||||
return (xsbti.MainResult) runMethod.invoke(instance, updatedConfiguration);
|
||||
} catch (InvocationTargetException e) {
|
||||
// This propogates xsbti.FullReload to the launcher
|
||||
// This propagates xsbti.FullReload to the launcher
|
||||
throw e.getCause();
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
|
|
@ -104,6 +112,22 @@ public class XMainConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private class FakeURLConnection extends URLConnection {
|
||||
public FakeURLConnection(URL url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
public void connect() throws IOException {}
|
||||
}
|
||||
|
||||
private void disableCachingOfURLConnections() {
|
||||
try {
|
||||
URLConnection conn = new FakeURLConnection(Paths.get(".").toUri().toURL());
|
||||
conn.setDefaultUseCaches(false);
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Replaces the AppProvider.loader method with a new loader that puts the sbt test interface
|
||||
* jar ahead of the rest of the sbt classpath in the classloading hierarchy.
|
||||
|
|
|
|||
|
|
@ -337,10 +337,9 @@ object EvaluateTask {
|
|||
|
||||
def evalPluginDef(pluginDef: BuildStructure, state: State): PluginData = {
|
||||
val root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root))
|
||||
val pluginKey = pluginData
|
||||
val config = extractedTaskConfig(Project.extract(state), pluginDef, state)
|
||||
val evaluated =
|
||||
apply(pluginDef, ScopedKey(pluginKey.scope, pluginKey.key), state, root, config)
|
||||
apply(pluginDef, ScopedKey(pluginData.scope, pluginData.key), state, root, config)
|
||||
val (newS, result) = evaluated getOrElse sys.error(
|
||||
"Plugin data does not exist for plugin definition at " + pluginDef.root
|
||||
)
|
||||
|
|
|
|||
|
|
@ -136,9 +136,10 @@ object PluginDiscovery:
|
|||
.getResources(resourceName)
|
||||
.asScala
|
||||
.toSeq
|
||||
.filter(onClasspath(classpath, converter)) flatMap { u =>
|
||||
IO.readLinesURL(u).map(_.trim).filter(!_.isEmpty)
|
||||
}
|
||||
.filter(onClasspath(classpath, converter))
|
||||
.flatMap { u =>
|
||||
IO.readLinesURL(u).map(_.trim).filter(!_.isEmpty)
|
||||
}
|
||||
|
||||
/** Returns `true` if `url` is an entry in `classpath`. */
|
||||
def onClasspath(classpath: Def.Classpath, converter: FileConverter)(url: URL): Boolean =
|
||||
|
|
|
|||
Loading…
Reference in New Issue