无法在测试外的Gradle中设置环境变量或属性

htrmnn0y  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(184)

bounty还有4天到期。回答此问题可获得+50声望奖励。scottstots正在寻找规范答案

我一直在尝试通过build.gradle文件设置一个简单的环境变量(或系统属性,无论什么工作),以从java方法(这不是集成测试的一部分)访问它,但在用尽了这个论坛和其他地方的几乎所有答案后,我仍然无法找到一个工作的解决方案。作为参考,我必须从src/main文件夹中的文件访问它。
我面临的问题是如果我这样指定它

test {
    environment 'PROJECT_DIR', "${projectDir}"
}

然后从我的java文件中这样访问它

String projectDir = System.getenv("PROJECT_DIR");

projectDir为空,因为我假设它不是测试文件的一部分。
如果我这样指定它

task MyTask(type: Exec) {
    environment 'PROJECT_DIR', "${projectDir}"
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn MyTask
}

和以前一样访问时,它会给出一个错误提示

Execution failed for task '<project-name>:MyTask'.
> execCommand == null!

如果我尝试对系统属性执行类似的操作,如

task setProp(type: Exec) {
    systemProperty 'PROJECT_DIR', "${projectDir}"
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn MyTask
}

然后访问它就像

String projectDir = System.getProperty("PROJECT_DIR");

它会以这个错误结束

Could not find method systemProperty() for arguments [PROJECT_DIR, <path>]

在一天结束的时候,我找不到任何可行的方法。但是,如果我将environment 'PROJECT_DIR', "${projectDir}"systemProperty 'PROJECT_DIR', "${projectDir}"包含在现有的JavaExec任务中,它们都可以工作。问题是我的文件不能被任何类型的JavaExec任务触发,因为它是更大的部署服务的一部分,所以通过build.gradle设置它似乎是我唯一的手段。
我想检查是否有我错过的东西,或者我可以让项目目录对我的java类可访问的其他方法。

k3bvogb1

k3bvogb11#

我面临的问题是如果我这样指定它

test {
    environment 'PROJECT_DIR', "${projectDir}"
}

这是设置执行test任务时可访问的环境变量的正确方法。
然后从我的java文件中这样访问它

String projectDir = System.getenv("PROJECT_DIR");

projectDir为空,因为我假设它不是测试文件的一部分。
无论它是“测试文件”还是“生产文件”。当您在test任务上设置环境变量时,它将在test任务执行期间可用和可访问。因此,在测试任务执行期间,它几乎不可能是null,除非您在某处输入错误或错过提供完整信息。
如果我这样指定它

task MyTask(type: Exec) {
    environment 'PROJECT_DIR', "${projectDir}"
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn MyTask
}

这实际上没有任何意义。您定义了一个Exec任务,这是一个执行某些可执行文件的任务。在执行该可执行文件期间,将设置环境变量。但您没有配置要执行哪个可执行文件,那么应该发生什么?
然后你让你的Java编译任务依赖于那个Exec任务,这就更没有意义了。除此之外,任何dependsOn都是一个代码气味(除非生命周期任务在左手边),应该避免。
和以前一样访问时,它会给出一个错误提示

Execution failed for task '<project-name>:MyTask'.
> execCommand == null!

是的,这是因为您没有告诉Exec任务执行哪个可执行文件,就像我上面解释的那样。
如果我尝试对系统属性执行类似的操作,如

task setProp(type: Exec) {
    systemProperty 'PROJECT_DIR', "${projectDir}"
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn MyTask
}

然后访问它就像

String projectDir = System.getProperty("PROJECT_DIR");

它会以这个错误结束

Could not find method systemProperty() for arguments [PROJECT_DIR, <path>]

与上面的最后一个例子相同的注解。但是另外,在执行任意可执行文件的Exec任务的上下文中,系统属性应该是什么。系统属性是Java特定的东西,所以你不能在一般的Exec任务上设置系统属性。
在一天结束的时候,我找不到任何可行的方法。但是,如果我将environment 'PROJECT_DIR', "${projectDir}"systemProperty 'PROJECT_DIR', "${projectDir}"包含在现有的JavaExec任务中,它们都可以工作。问题是我的文件不能被任何类型的JavaExec任务触发,因为它是一个更大的部署服务的一部分,所以通过build.gradle设置它似乎是我唯一的手段。
如果我理解正确的话,那么这一段是你问题中最重要的部分。我是否理解正确了,你想在构建时使用构建脚本设置此属性,但当在Gradle之外的“更大的已部署服务”中运行时,又希望它对你的生产代码可用?
这是行不通的,你在Gradle中设置的内容只在你设置的任务执行期间可用。它们不能自动持久化或类似的东西。这也完全违背了它们的用途。它们在那里是为了让你可以在运行时配置东西,而不是在构建时,例如程序的用户可以配置某些东西。
如果你想在构建时设置属性,然后在运行时访问它,你需要将这个值生成到一个文件中。例如,你可以使用WriteProperties类型的任务,但要注意,你应该正确地将它配置为任务生成资源,将它作为参数给sourceSets.main.resources.srcDir(...),或者更简单的方法是在资源中有一个模板文件,然后配置processResources任务来填充模板中的占位符,例如使用expand。然后在运行时,您可以读取该属性文件以获取所需的值。

相关问题