gradle应用程序插件和系统环境变量

时间:2014-09-12 18:21:24

标签: gradle

在我的项目中,我尝试使用build.gradle中的系统环境配置我的应用程序:

apply plugin: 'application'
applicationDefaultJvmArgs = ["-Ddw.server.applicationConnectors[0].port=${System.env.PORT}"]

如果将PORT设置为常量,则可以这样工作,假设为9001.但是如果我将PORT更改为另一个变量,则可执行脚本不会更改,它已经编译为build / install / bin中的旧值PORT / {executable-script},像这样:

DEFAULT_JVM_OPTS='"-Ddw.server.applicationConnectors[0].port=9001"'

而不是我想要的,

DEFAULT_JVM_OPTS='"-Ddw.server.applicationConnectors[0].port=$PORT"'

有没有办法告诉应用程序插件使用系统环境变量而不是评估system.env变量?

顺便说一句,我也试过没有单引号来避免评估$ PORT表达式

applicationDefaultJvmArgs = ['-Ddw.server.applicationConnectors[0].port=$PORT']

applicationDefaultJvmArgs = ['-Ddw.server.applicationConnectors[0].port=\$PORT']

但是这两个都编译成了这个不起作用。

DEFAULT_JVM_OPTS='"-Ddw.server.applicationConnectors[0].port=\$PORT"'

1 个答案:

答案 0 :(得分:8)

(我是提交applicationDefaultJvmArgs功能的Gradle撰稿人)

如果你写" $ {System.env.PORT}"在ApplicationDefaultJvmArgs元素中,PORT环境变量在构建时被替换,即在开发者机器上,在Gradle甚至看到它之前被替换,然后该值被用在启动脚本中,这就是你所看到的。

在Unix启动脚本中引用applicationDefaultJvmArgs中的文字$并不是一个错误,这是故意的。 applicationDefaultJvmArgs数组可以在所有目标平台(即Unix和Windows)上移植。也就是说,生成Unix / Windows启动脚本,以便两个平台上启动的JVM完全看到在构建时传递到applicationDefaultJvmArgs的字符串参数。这意味着必须在Unix启动脚本中引用任何shell元字符,例如$中的字符串,这样如果你有文字字符串' $ PORT'在其中一个论点中,它完全像那样再现,即没有发生shell变量扩展。如果" $ PORT"在$之前没有\的时候写入unix启动脚本,然后启动脚本会在Unix上执行你想要的操作。但是在Windows上,起始脚本是cmd批处理文件,$没有特殊含义(相反,%%必须用于变量扩展),所以字符串" $ PORT"将直接传递给JVM,您的程序将无法按预期工作。您可能不关心Windows(实际上我也不关心,至少不是这样),但Gradle,特别是具有其所有功能的应用程序插件,意味着可以在所有支持的平台上完全移植,所以这就是事情现在就实施了。

如果您确实希望在运行时扩展$ PORT变量,即在用户计算机上运行入门脚本时,则必须在后处理步骤中相应地修改生成的入门脚本。例如:

startScripts {
    doLast {
        unixScript.text = unixScript.text.replace('\\$PORT', '$PORT') 
        windowsScript.text = windowsScript.text.replace('\\$PORT', '%PORT%') //untested
    }
}

对于未来,可能会考虑在applicationDefaultJvmArgs中为运行时环境变量提供某种独立于平台的表示法,然后应用程序插件会将每个入门脚本中的表单扩展为正确的特定于平台的变量表示法。但目前还没有计划,AFAIK。