ScriptEngine
has a context
property of type ScriptContext
, and that has writer
and errorWriter
properties. These are supposed to be where scripts emit their stdout and stderr to. See this for example.
However, I cannot seem to get that working with the Kotlin engine.
Starting with the official test sample project, I added these four tests:
@Test
fun testSystemOutRedir() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val out = ByteArrayOutputStream()
System.setOut(PrintStream(out))
val comp1 = engine.compile("println(1)")
val res1 = comp1.eval()
Assert.assertNull(res1)
Assert.assertEquals("1\n", out.toString())
}
@Test
fun testEngineOutRedir() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val out = StringWriter()
engine.context.writer = PrintWriter(out)
val comp1 = engine.compile("println(1)")
val res1 = comp1.eval()
Assert.assertNull(res1)
Assert.assertEquals("1\n", out.buffer.toString())
}
@Test
fun testSystemErrRedir() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val out = ByteArrayOutputStream()
System.setErr(PrintStream(out))
val comp1 = engine.compile("System.err.println(1)")
val res1 = comp1.eval()
Assert.assertNull(res1)
Assert.assertEquals("1\n", out.toString())
}
@Test
fun testEngineErrRedir() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val out = StringWriter()
engine.context.errorWriter = PrintWriter(out)
val comp1 = engine.compile("System.err.println(1)")
val res1 = comp1.eval()
Assert.assertNull(res1)
Assert.assertEquals("1\n", out.buffer.toString())
}
The two testSystem...()
functions test redirecting stdout and stderr by means of System.setOut()
and System.setErr()
. Those tests succeed.
The two testEngine...()
functions test redirecting stdout and stderr by means of ScriptContext
. Those tests fail.
I also have this test that both sets the system stdout and overrides the ScriptContent
writer
:
@Test
fun testComboOutRedir() {
val engine = ScriptEngineManager().getEngineByExtension("kts") as KotlinJsr223JvmLocalScriptEngine
val out = ByteArrayOutputStream()
System.setOut(PrintStream(out))
val outWriter = StringWriter()
engine.context.writer = PrintWriter(outWriter)
val comp1 = engine.compile("println(1)")
val res1 = comp1.eval()
Assert.assertNull(res1)
Assert.assertEquals("1\n", out.toString())
Assert.assertEquals("1\n", outWriter.buffer.toString())
}
This fails on the final Assert.assertEquals()
call. In particular, this shows that even though I specifically request to have stdout go to my PrintWriter
, stdout still goes to the system stdout.
Am I doing something wrong?
Thanks!