Reputation: 2044
Background: we are setting current project version as system environment:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<forkMode>always</forkMode>
<environmentVariables>
<project.target>${project.build.outputDirectory}</project.target>
<project.version>${project.version}</project.version>
</environmentVariables>
</configuration>
</plugin>
And then we get the value in the test using System.getenv("project.version");
and this works just fine on all machines… except for one.
The problematic machine is new AWS EC2 instance with Ubuntu 16.04 LTS. The setup and configuration looks ok. I checked both OpenJDK and OracleJDK, latest versions, I also checked included java and maven version:
$ java -version
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
maven
$ mvn -version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 1.8.0_151, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-1049-aws", arch: "amd64", family: "unix"
and the newest available for download:
$ mvn --version
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T07:58:13Z)
Maven home: /usr/share/maven
Java version: 1.8.0_161, vendor: Oracle Corporation
Java home: /usr/lib/jvm/jdk1.8.0_161/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-1049-aws", arch: "amd64", family: "unix"
And the issue persists. Weird thing is that the forking is enabled (required) and log entry shows that the variables are being set:
[DEBUG] Setting environment variable [project.version]=[4.0.0-SNAPSHOT]
Then we have test execution with forking:
[DEBUG] boot(compact) classpath: surefire-booter-2.19.1.jar surefire-api-2.19.1.jar test-classes classes junit-4.10.jar hamcrest-core-1.1.jar …-4.0.0-SNAPSHOT.jar surefire-junit4-2.19.1.jar
Forking command line: /bin/sh -c cd /mnt/ebsVolume/
And yet System.getenv("project.version");
returns null
Upvotes: 6
Views: 6143
Reputation: 3140
Environment variables of the unix process cannot contain some specific characters in thier name. See doc here. Shortly, you environment variables do not stick to this naming rules, and maven simply does not register them during running you test cases, you can change names for example like this:
project.target --> PROJECT_TARGET
project.version --> PROJECT_VERSION
and it would work. Sadly, maven surefire plugin seems not to even warn you that the name syntax of some env variable is not correct. Hope it helped, have a nide day!
Upvotes: 2
Reputation: 6288
Maybe not the answer to the raised question but because other users like me are reading this thread this might be still useful: I found out that setting a variable only works if it is not already set (at least under my Windows 10 system), i.e. the variable must be unset with excludedEnvironmentVariables
before to be applied. Example:
FOOBAR
is already set in the environment to C:\test.conf
<environmentVariables>
<FOOBAR>${project.build.directory}/test.conf</FOOBAR>
</environmentVariables>
<excludedEnvironmentVariables>FOOBAR</excludedEnvironmentVariables>
is needed to set the intended value, otherwise the one from the environment is used.Upvotes: 4
Reputation: 96
I just had the same problem taking a project from Fedora to Linux Mint. I ran the same tests endless times on Fedora, macOS, Windows 7 and Windows 10 – never any problems. So I was quite surprised seeing them fail doing mvn test
on the bash command line. It got even stranger seeing them pass when executed with the intellij test-runner. Running test
from the maven tool window within intellij failed again.
@ilooner's systemPropertyVariables approach worked, but then I had to replace environment variables with system properties and use System.getProperty()
instead of System.getenv()
. This was not possible in my case.
Setup was always OpenJDK 11, junit5 and Maven 3.6.x with surefire-plugin 3.0.0-M3. But this is not the issue here. The problem is the name of the variable. I tried to define it directly in the shell to see if the test would see it and this happened:
$ export project.version=42
bash: export: `project.version=42': not a valid identifier
As it turned out, since bash 3 you cannot define a environment variable containing a .
! No matter if cygwin, macOS or Linux. As stated in Allowed characters in Linux environment variable names, you should stick uppercase letters, digits and the underscore. This seems to be just a recommendation and not for all shells, but you never know where your app will run some day.
Back to your question. If you'd use PROJECT_TARGET
instead of project.target
, it'll most likely work. On my current setup it worked with project_target
as well, but this might cause trouble elsewhere.
I have no answer though, why the surefire-plugin handles variables.with.dots
on Fedora 30, macOS Mojave and cygin, but not on Mint 19.2 nor Ubuntu 18.4.. The last two use bash 4.4 while the first two bash 5.0. So it could be connected to the bash version.
Windows allows dots, so it seems logical that it works there. But still, there is no point testing environment.variables.with.dots
, cause in some systems they just don't exist. If you wanna stay portable, you should avoid them at all.
Upvotes: 2