Search code examples
gradlejavafxjava-11gradle-kotlin-dsljavafx-11

Gradle Kotlin DSL equivalent for Groovy DSL 'run'?


I am trying to build a simple JavaFX 11 program with Kotlin and Java 11, using Gradle, following the instructions here. However, this page uses Gradle's Groovy DSL, and I am trying to use the Kotlin DSL. Surprisingly, my Google searches have not turned up a document that maps each Groovy construct to its equivalent Kotlin construct or explains in general how to convert Groovy DSL code to equivalent Kotlin DSL code. (This seems like a big oversight in the Gradle documentation!).

In particular, this document contains the following Groovy code:

compileJava {
    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath,
            '--add-modules', 'javafx.controls'
        ]
    }
}

run {
     doFirst {
         jvmArgs = [
             '--module-path', classpath.asPath,
             '--add-modules', 'javafx.controls'
         ]
    }
}

As far as I can tell, the Kotlin equivalent to the first part appears to be:

tasks.withType<JavaCompile> {
    options.compilerArgs.addAll(arrayOf(
        "--module-path", classpath.asPath,
        "--add-modules", "javafx.controls"
    ))
}

However, I have not been able to figure out what the Kotlin DSL equivalent to the second part is. Note that 'run' is a standard function extension in Kotlin's standard library, so it does not appear that the Kotlin version of this code can use the name 'run' for the same purpose in the Kotlin DSL.

(Note: I considered trying to use a plugin for the JavaFX support (as described by this page, for instance), but the plugin seems quite complicated to use, and I already am having enough problems with the number of complications in this project that I am hesitant to introduce a very-lightly-documented open-source plugin into the mix. I really am trying to produce the simplest possible "Hello, World" program in JavaFX/Gradle at the moment, and this has so far seemed surprisingly difficult.).

Any help would be appreciated.


Solution

  • Using the configuration avoidance APIs, the equivalent to the second block is:

    tasks.named<JavaExec>("run") {
        doFirst {
            jvmArgs = listOf("--module-path", classpath.asPath,"--add-modules", "javafx.controls")
        }
    }
    

    The key is that run has the JavaExec type, which like any task's type can be discovered by creating a task to print the class of the task that you then run:

    tasks.register("getName") {
        doFirst {
            print("Class name: ${tasks["run"].javaClass}")
        }
    }
    

    Note that as your JavaFX application grows, you will need to specify additional modules like this:

    tasks.named<JavaExec>("run") {
        doFirst {
            jvmArgs = listOf("--module-path", classpath.asPath,
                "--add-modules", "javafx.base,javafx.controls,javafx.graphics")
        }
    }