1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
package dotty.tools.dotc
package vulpix
import java.io.{
File => JFile,
InputStream, ObjectInputStream,
OutputStream, ObjectOutputStream,
ByteArrayOutputStream, PrintStream
}
import java.lang.reflect.InvocationTargetException
import dotty.tools.dotc.vulpix.Statuses._
object ChildMain {
val realStdin = System.in
val realStderr = System.err
val realStdout = System.out
private def runMain(dir: JFile): Status = {
def renderStackTrace(ex: Throwable): String =
ex.getStackTrace
.takeWhile(_.getMethodName != "invoke0")
.mkString(" ", "\n ", "")
def resetOutDescriptors(): Unit = {
System.setOut(realStdout)
System.setErr(realStderr)
}
import java.net.{ URL, URLClassLoader }
val printStream = new ByteArrayOutputStream
try {
// Do classloading magic and running here:
val ucl = new URLClassLoader(Array(dir.toURI.toURL))
val cls = ucl.loadClass("Test")
val meth = cls.getMethod("main", classOf[Array[String]])
try {
val ps = new PrintStream(printStream)
System.setOut(ps)
System.setErr(ps)
Console.withOut(printStream) {
Console.withErr(printStream) {
// invoke main with "jvm" as arg
meth.invoke(null, Array("jvm"))
}
}
resetOutDescriptors()
} catch {
case t: Throwable =>
resetOutDescriptors()
throw t
}
new Success(printStream.toString("utf-8"))
}
catch {
case ex: NoSuchMethodException =>
val msg = s"test in '$dir' did not contain method: ${ex.getMessage}"
new Failure(msg, renderStackTrace(ex.getCause))
case ex: ClassNotFoundException =>
val msg = s"test in '$dir' did not contain class: ${ex.getMessage}"
new Failure(msg, renderStackTrace(ex.getCause))
case ex: InvocationTargetException =>
val msg = s"An exception ocurred when running main: ${ex.getCause}"
new Failure(msg, renderStackTrace(ex.getCause))
}
}
def main(args: Array[String]): Unit = {
val stdin = new ObjectInputStream(System.in);
val stdout = new ObjectOutputStream(System.out);
while (true) {
val dir = stdin.readObject().asInstanceOf[JFile]
stdout.writeObject(runMain(dir))
stdout.flush()
}
}
}
|