Search code examples
kotlingradle-kotlin-dsl

How do I pass default JVM args in a Gradle script while allowing variables to be expanded?


I've got the following in my build.gradle.kts file:

plugins {
    kotlin("jvm") version "1.9.20"
    application
}

application {
    mainClass.set("MainKt")
    applicationDefaultJvmArgs = listOf("-Dlog_dir=MY_APP_HOME/log")
}

tasks.withType<CreateStartScripts>().configureEach {
    doLast {
        windowsScript.text = windowsScript.text.replace("MY_APP_HOME", "%APP_HOME%")
        unixScript.text = unixScript.text.replace("MY_APP_HOME", "\$APP_HOME")
    }
}

I've discovered that the unix shell script wraps my JVM args in single and double quotes.

DEFAULT_JVM_OPTS='"-Dlog_dir=$APP_HOME/log"'

Because of this, the variable $APP_HOME is not expanded and the log dir for my application is literally "$APP_HOME/log".

I cannot find any way to prevent this behavior. How can I get the variable to be expanded properly?


Solution

  • You can replace your placeholder "MY_APP_HOME" with the application home directory in a JVM argument using1:

    tasks.withType<CreateStartScripts>().configureEach {
        doLast {
            windowsScript.writeText(
                windowsScript.readText().replace("MY_APP_HOME", "%APP_HOME%")
            unixScript.writeText(
                unixScript.readText().replace("MY_APP_HOME", "'\$APP_HOME'")
            )
        }
    }
    

    I have used Kotlin's writeText and readText functions as the text operator on a File is only in Groovy, I believe.


    1Note this is guaranteed by an integration test in the Gradle project (written in Groovy): see GitHub.

    The test code has two extra backslashes in its definition of the text to replace in the unix script: it writes "'\\\$APP_HOME'". Those extra backslashes are there because the test build file code that contains this is itself wrapped in triple quotes.