Repository: JetBrains/kotlin
File: ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt (Kotlin)

Code before:
        setClasspath(classpath)
    }

    override fun fillSpecificArguments() {
        args.add("-d")
        args.add(output!!.canonicalPath)

        compileClasspath?.let {
            args.add("-classpath")
            args.add(it.list().joinToString(pathSeparator))
        }


        if (moduleName == null) {
            moduleName = defaultModuleName
        }

        moduleName?.let {
            args.add("-module-name")
            args.add(moduleName!!)
        }

        if (noStdlib) args.add("-no-stdlib")
        if (noReflect) args.add("-no-reflect")
        if (includeRuntime) args.add("-include-runtime")
    }

    override fun execute() {
        if (!fork)
            super.execute()
        else {
            exec()
        }
    }

    private fun exec(): Int {
        val javaHome = System.getProperty("java.home")
        val javaBin = javaHome + File.separator + "bin" + File.separator + "java"
        val classpath = System.getProperty("java.class.path")

        val command = ArrayList<String>()
        command.add(javaBin)
        command.addAll(cmdl.vmCommand.arguments)
        command.add("-cp")
        command.add(classpath + pathSeparator + KotlinAntTaskUtil.compilerJar.canonicalPath)
        command.add(compilerFqName)
        command.addAll(additionalArguments.flatMap { it.parts.toList() })
        compileClasspath?.let {
            command.add("-cp")
            command.add(it.toString())
        }

Review comment (suggestion):
It seems that overriding `execute` resulted in the fork mode not having all the logic that was there, such as:
* filling different compiler arguments (`-nowarn`, `-verbose`, `-include-runtime`, `-module-name`, etc.)
* running the compiler with `execFullPathsInMessages` as opposed to the default mode when paths in compiler messages are relative
* logging what's being compiled
* throwing `BuildException` on compilation error

Code after:

    override fun fillSpecificArguments() {
        args.add("-d")
        args.add(output!!.canonicalPath)

        compileClasspath?.let {
            args.add("-classpath")
            args.add(it.list().joinToString(pathSeparator))
        }


        if (moduleName == null) {
            moduleName = defaultModuleName
        }

        moduleName?.let {
            args.add("-module-name")
            args.add(moduleName!!)
        }

        if (noStdlib) args.add("-no-stdlib")
        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<String>()
        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 <code>null</code> to disable a timeout for the subprocess.