如何在Gradle脚本中传递默认JVM参数并实现变量正确展开?
问题描述
我在build.gradle.kts中做了如下配置:
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") } }
生成的Unix Shell脚本里,JVM参数被包裹在单双嵌套引号中:
DEFAULT_JVM_OPTS='"-Dlog_dir=$APP_HOME/log"'
这导致$APP_HOME无法被Shell展开,应用实际使用的日志目录是字面量"$APP_HOME/log",请问怎么让变量正确展开?
解决方案
问题出在CreateStartScripts生成脚本时,会自动给包含特殊字符(这里是$)的JVM参数添加引号,加上手动替换后引入的变量,就出现了嵌套引号的问题。可以通过以下两种方式解决:
方法1:修改替换逻辑,修正引号结构
在doLast步骤中,不仅替换变量,还要调整引号的嵌套格式:
tasks.withType<CreateStartScripts>().configureEach { doLast { windowsScript.text = windowsScript.text.replace("MY_APP_HOME", "%APP_HOME%") // 先替换变量,再去除多余的嵌套引号 var unixContent = unixScript.text.replace("MY_APP_HOME", "\$APP_HOME") unixContent = unixContent.replace("DEFAULT_JVM_OPTS='\"", "DEFAULT_JVM_OPTS=\"") unixContent = unixContent.replace("\"'", "\"") unixScript.text = unixContent } }
处理后生成的配置会变成:
DEFAULT_JVM_OPTS="-Dlog_dir=$APP_HOME/log"
Shell就能正常展开$APP_HOME变量。
方法2:自定义启动脚本模板
从根源上避免引号问题,直接定制脚本模板:
- 先执行一次
createStartScripts任务,在build/scripts目录下找到生成的Unix启动脚本,复制其内容。 - 在项目
src/main/resources目录下创建unixStartScript.txt,将复制的内容粘贴进去,把DEFAULT_JVM_OPTS部分修改为:
DEFAULT_JVM_OPTS="-Dlog_dir=${APP_HOME}/log"
- 在
build.gradle.kts中指定使用自定义模板:
tasks.withType<CreateStartScripts>().configureEach { unixStartScriptGenerator.template = resources.text.fromFile("src/main/resources/unixStartScript.txt") doLast { windowsScript.text = windowsScript.text.replace("MY_APP_HOME", "%APP_HOME%") } }
这种方式无需后期替换,逻辑更清晰易维护。
内容的提问来源于stack exchange,提问作者Mirrana
相关产品推荐
相关产品推荐

