mirror of
https://github.com/sbt/sbt.git
synced 2026-08-29 01:24:09 +02:00
[2.0.x] fix: keep worker classloader open for shutdown hooks (#9639)
This commit is contained in:
committed by
Eugene Yokota
parent
5cee896c5f
commit
24324be9e5
@@ -0,0 +1,21 @@
|
||||
Global / localCacheDirectory := baseDirectory.value / "diskcache"
|
||||
scalaVersion := "3.8.4"
|
||||
|
||||
Test / fork := true
|
||||
|
||||
libraryDependencies += "org.scalameta" %% "munit" % "1.0.4" % Test
|
||||
|
||||
val check = TaskKey[Unit]("check", "Verify the shutdown hook could load classes.")
|
||||
|
||||
check := Def.uncached {
|
||||
val file = baseDirectory.value / "hook-result.txt"
|
||||
val deadline = System.currentTimeMillis + 30000
|
||||
def content: String = if (file.exists) IO.read(file).trim else ""
|
||||
while (content.isEmpty || content.startsWith("PENDING")) {
|
||||
if (System.currentTimeMillis > deadline)
|
||||
sys.error(s"shutdown hook never completed: '$content'")
|
||||
Thread.sleep(500)
|
||||
}
|
||||
val result = content
|
||||
if (!result.startsWith("OK")) sys.error(s"shutdown hook failed: '$result'")
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package repro
|
||||
|
||||
object LazilyLoaded {
|
||||
val marker: String = "loaded"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package repro
|
||||
|
||||
import java.nio.file.{ Files, Paths }
|
||||
|
||||
class ShutdownHookTest extends munit.FunSuite {
|
||||
test("shutdown hook can load classes after the test run") {
|
||||
val out = Paths.get("hook-result.txt")
|
||||
Files.writeString(out, "PENDING: shutdown hook did not run" + System.lineSeparator)
|
||||
val _ = sys.addShutdownHook {
|
||||
val result =
|
||||
try {
|
||||
Class.forName("repro.LazilyLoaded$")
|
||||
"OK: classloader still works at JVM shutdown"
|
||||
} catch {
|
||||
case t: Throwable => s"FAIL: $t"
|
||||
}
|
||||
Files.writeString(out, result + System.lineSeparator)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
> testFull
|
||||
> check
|
||||
@@ -188,12 +188,11 @@ public final class WorkerMain {
|
||||
throw new RuntimeException("missing jvmRunInfo element");
|
||||
}
|
||||
RunInfo.JvmRunInfo jvmRunInfo = info.jvmRunInfo;
|
||||
try (URLClassLoader cl = createClassLoader(jvmRunInfo, ClassLoader.getSystemClassLoader())) {
|
||||
Class<?> mainClass = cl.loadClass(jvmRunInfo.mainClass);
|
||||
Method mainMethod = mainClass.getMethod("main", String[].class);
|
||||
String[] mainArgs = jvmRunInfo.args.stream().toArray(String[]::new);
|
||||
mainMethod.invoke(null, (Object) mainArgs);
|
||||
}
|
||||
URLClassLoader cl = createClassLoader(jvmRunInfo, ClassLoader.getSystemClassLoader());
|
||||
Class<?> mainClass = cl.loadClass(jvmRunInfo.mainClass);
|
||||
Method mainMethod = mainClass.getMethod("main", String[].class);
|
||||
String[] mainArgs = jvmRunInfo.args.stream().toArray(String[]::new);
|
||||
mainMethod.invoke(null, (Object) mainArgs);
|
||||
} else {
|
||||
throw new RuntimeException("only jvm is supported");
|
||||
}
|
||||
@@ -207,9 +206,8 @@ public final class WorkerMain {
|
||||
if (jvmRunInfo.classpath.isEmpty()) {
|
||||
ForkTestMain.main(id, info, this.jsonOut, parent);
|
||||
} else {
|
||||
try (URLClassLoader cl = createClassLoader(jvmRunInfo, parent)) {
|
||||
ForkTestMain.main(id, info, this.jsonOut, cl);
|
||||
}
|
||||
URLClassLoader cl = createClassLoader(jvmRunInfo, parent);
|
||||
ForkTestMain.main(id, info, this.jsonOut, cl);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("only jvm is supported");
|
||||
|
||||
Reference in New Issue
Block a user