From 0110b4e4b4df0350e600a6bd1eb3050eb8b4b260 Mon Sep 17 00:00:00 2001 From: scaventz Date: Fri, 4 Dec 2020 18:00:54 +0800 Subject: [PATCH] Ant: Add support for fork-mode #KT-44293 --- .../jetbrains/kotlin/ant/Kotlin2JvmTask.kt | 53 ++++++++++++++++++- .../kotlin/ant/KotlinCompilerBaseTask.kt | 2 +- .../ant/jvm/fork/build.log.expected | 16 ++++++ .../integration/ant/jvm/fork/build.xml | 25 +++++++++ .../integration/ant/jvm/fork/hello.kt | 5 ++ .../ant/jvm/fork/premain/Premain.java | 14 +++++ .../ant/jvm/forkOnError/build.log.expected | 24 +++++++++ .../integration/ant/jvm/forkOnError/build.xml | 25 +++++++++ .../ant/jvm/forkOnError/premain/Premain.java | 14 +++++ .../integration/ant/jvm/forkOnError/test.kt | 5 ++ .../integration/AntTaskTestGenerated.java | 10 ++++ 11 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/integration/ant/jvm/fork/build.log.expected create mode 100644 compiler/testData/integration/ant/jvm/fork/build.xml create mode 100644 compiler/testData/integration/ant/jvm/fork/hello.kt create mode 100644 compiler/testData/integration/ant/jvm/fork/premain/Premain.java create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/build.log.expected create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/build.xml create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/test.kt diff --git a/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt b/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt index aea749a85e8..33f946e31f5 100644 --- a/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt +++ b/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt @@ -16,9 +16,12 @@ package org.jetbrains.kotlin.ant -import org.apache.tools.ant.types.Path -import org.apache.tools.ant.types.Reference +import org.apache.tools.ant.BuildException +import org.apache.tools.ant.taskdefs.Execute +import org.apache.tools.ant.taskdefs.Redirector +import org.apache.tools.ant.types.* import java.io.File.pathSeparator +import java.io.File.separator class Kotlin2JvmTask : KotlinCompilerBaseTask() { override val compilerFqName = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler" @@ -28,6 +31,9 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() { var noReflect: Boolean = false + private val cmdl = CommandlineJava() + var fork: Boolean = false + private var compileClasspath: Path? = null fun setClasspath(classpath: Path) { @@ -73,4 +79,47 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() { if (noReflect) args.add("-no-reflect") if (includeRuntime) args.add("-include-runtime") } + + override fun execute() { + if (!fork) + super.execute() + else { + exec() + } + } + + private fun exec() { + val javaHome = System.getProperty("java.home") + val javaBin = javaHome + separator + "bin" + separator + "java" + val redirector = Redirector(this) + + fillArguments() + + val command = ArrayList() + command.add(javaBin) + command.addAll(cmdl.vmCommand.arguments) // jvm args + command.add("-Dorg.jetbrains.kotlin.cliMessageRenderer=FullPath") // same MessageRenderer as non-forking mode + command.add("-cp") + command.add(KotlinAntTaskUtil.compilerJar.canonicalPath) + command.add(compilerFqName) + command.addAll(args) // compiler args + + // streamHandler: used to handle the input and output streams of the subprocess. + // watchdog: a watchdog for the subprocess or null to disable a timeout for the subprocess. + // TODO: support timeout for the subprocess + val exe = Execute(redirector.createHandler(), null) + exe.setAntRun(getProject()) + exe.commandline = command.toTypedArray() + log("Executing command: ${command.joinToString(" ")}", LogLevel.DEBUG.level) + log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]") + val exitCode = exe.execute() + redirector.complete() + if (failOnError && exitCode != 0) { + throw BuildException("Compile failed; see the compiler error output for details.") + } + } + + fun createJvmarg(): Commandline.Argument { + return cmdl.createVmArgument() + } } diff --git a/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt b/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt index 417068ef8a8..f39bfdadf2a 100644 --- a/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt +++ b/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt @@ -80,7 +80,7 @@ abstract class KotlinCompilerBaseTask : Task() { fillSpecificArguments() } - final override fun execute() { + override fun execute() { fillArguments() val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName) diff --git a/compiler/testData/integration/ant/jvm/fork/build.log.expected b/compiler/testData/integration/ant/jvm/fork/build.log.expected new file mode 100644 index 00000000000..6a303908cd8 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/build.log.expected @@ -0,0 +1,16 @@ +OUT: +Buildfile: [TestData]/build.xml + +premain: + [javac] Compiling 1 source file to [Temp] + [jar] Building jar: [Temp]/premain.jar + +build: + [kotlinc] Compiling [[TestData]] => [[Temp]/fork.jar] + [kotlinc] -Xms64m + [kotlinc] -Xmx128m + +BUILD SUCCESSFUL +Total time: [time] + +Return code: 0 diff --git a/compiler/testData/integration/ant/jvm/fork/build.xml b/compiler/testData/integration/ant/jvm/fork/build.xml new file mode 100644 index 00000000000..5dffa59b1db --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/build.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compiler/testData/integration/ant/jvm/fork/hello.kt b/compiler/testData/integration/ant/jvm/fork/hello.kt new file mode 100644 index 00000000000..4106d5b5fdc --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/hello.kt @@ -0,0 +1,5 @@ +package hello + +fun main() { + println(0 as String) +} diff --git a/compiler/testData/integration/ant/jvm/fork/premain/Premain.java b/compiler/testData/integration/ant/jvm/fork/premain/Premain.java new file mode 100644 index 00000000000..48fa3a0401f --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/premain/Premain.java @@ -0,0 +1,14 @@ +import java.lang.instrument.Instrumentation; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.List; + +public class Premain { + public static void premain(String agentArgs, Instrumentation inst) { + RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); + List arguments = bean.getInputArguments(); + arguments.stream().filter(param -> + param.startsWith("-Xmx") || param.startsWith("-Xms") + ).sorted().forEach(System.out::println); + } +} diff --git a/compiler/testData/integration/ant/jvm/forkOnError/build.log.expected b/compiler/testData/integration/ant/jvm/forkOnError/build.log.expected new file mode 100644 index 00000000000..2d6555d5737 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/build.log.expected @@ -0,0 +1,24 @@ +OUT: +Buildfile: [TestData]/build.xml + +premain: + [javac] Compiling 1 source file to [Temp] + [jar] Building jar: [Temp]/premain.jar + +build: + [kotlinc] Compiling [[TestData]] => [[Temp]/fork.jar] + [kotlinc] -Xms64m + [kotlinc] -Xmx128m + [kotlinc] error: warnings found and -Werror specified + [kotlinc] [TestData]/test.kt:4:15: warning: this cast can never succeed + [kotlinc] println(0 as String) + [kotlinc] ^ + +ERR: + +BUILD FAILED +[TestData]/build.xml:18: Compile failed; see the compiler error output for details. + +Total time: [time] + +Return code: 1 diff --git a/compiler/testData/integration/ant/jvm/forkOnError/build.xml b/compiler/testData/integration/ant/jvm/forkOnError/build.xml new file mode 100644 index 00000000000..e62ad865146 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/build.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java b/compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java new file mode 100644 index 00000000000..48fa3a0401f --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java @@ -0,0 +1,14 @@ +import java.lang.instrument.Instrumentation; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.List; + +public class Premain { + public static void premain(String agentArgs, Instrumentation inst) { + RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); + List arguments = bean.getInputArguments(); + arguments.stream().filter(param -> + param.startsWith("-Xmx") || param.startsWith("-Xms") + ).sorted().forEach(System.out::println); + } +} diff --git a/compiler/testData/integration/ant/jvm/forkOnError/test.kt b/compiler/testData/integration/ant/jvm/forkOnError/test.kt new file mode 100644 index 00000000000..f6bac26d258 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/test.kt @@ -0,0 +1,5 @@ +package hello + +fun main() { + println(0 as String) +} \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java index 749b799377d..01878446123 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java @@ -44,6 +44,16 @@ public class AntTaskTestGenerated extends AbstractAntTaskTest { runTest("compiler/testData/integration/ant/jvm/failOnErrorByDefault/"); } + @TestMetadata("fork") + public void testFork() throws Exception { + runTest("compiler/testData/integration/ant/jvm/fork/"); + } + + @TestMetadata("forkOnError") + public void testForkOnError() throws Exception { + runTest("compiler/testData/integration/ant/jvm/forkOnError/"); + } + @TestMetadata("helloWorld") public void testHelloWorld() throws Exception { runTest("compiler/testData/integration/ant/jvm/helloWorld/");