The problem I'm facing is that if I specify it like this
test {
environment 'PROJECT_DIR', "${projectDir}"
}
This is exactly the right way to set an environment variable that is accessible while you are executing the test
task.
and access it like this from my java file
String projectDir = System.getenv("PROJECT_DIR");
projectDir is null because I assume it's not part of test files.
It does not matter whether it is a "test file" or a "production file".
As you set the environment variable on the test
task, it will be available and accessible during execution of the test
task. So it can hardly be that it is null
during the exeuction of the test task, except if you have a typo somewhere or missed to provide complete information.
If I specify it like this
task MyTask(type: Exec) {
environment 'PROJECT_DIR', "${projectDir}"
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn MyTask
}
This does not make any sense, really.
You define an Exec
task, which is a task that executes some executable.
During execution of that executable, the environment variable would be set.
But you do not configure which executable to execute, so what should happen?
Then you make your Java compilation task depend on that Exec
task which makes even less sense. Besides that any dependsOn
is a code-smell (except if a lifecycle task is on the left-hand side) and should be avoided.
and accessing the same way as before, it gives an error saying
Execution failed for task '<project-name>:MyTask'.
> execCommand == null!
Yep, that is because you did not tell the Exec
task which executable to execute as I just explained above.
If I try to do something similar for system property like
task setProp(type: Exec) {
systemProperty 'PROJECT_DIR', "${projectDir}"
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn MyTask
}
and accessing it like
String projectDir = System.getProperty("PROJECT_DIR");
it ends up with this error
Could not find method systemProperty() for arguments [PROJECT_DIR, <path>]
Same comments as with the last example above.
But additionally, what should a system property be in the context of an Exec
task that executes an arbitrary executable.
System properties are a Java specific thing, so you cannot set a system property on a generic Exec
task.
At the end of the day, I could find nothing that works out. However, both environment 'PROJECT_DIR', "${projectDir}"
and systemProperty 'PROJECT_DIR', "${projectDir}"
work if I include them in an existing JavaExec task. The problem is that my file cannot be triggered by any kind of JavaExec tasks as it is part of a bigger deployed service, so setting it through build.gradle seems like my only resort.
If I got you right here, then this paragraph is the most important in your question.
Do I get you right, that you want to set this property at build time using your build script, but then expect it to be available to your production code when running outside of Gradle in the "bigger deployed service"?
This cannot work, what you set in Gradle is only available during the execution of the task you are setting them on. They cannot be persisted automagically or something like that. That would also be completely against what they are for. They are there so that you can configure things at runtime, not at build time, so that for example a user of a program can configure certain things.
If you want to set the property at build time and then access it at runtime, you need to generate this value into a file. For this you can for example use a task of type WriteProperties
, but be aware that you should properly configure it as task generating resources, by giving it to sourceSets.main.resources.srcDir(...)
as argument, or maybe the easier way is to have a template file in your resources and then configure the processResources
task to fill in the placeholders in the template for example using expand
. Then at runtime you can read that properties file to get the value you need.