I'm confused about the correct way to set a property for some unit tests via the command line when using Maven. There are a number of questions (e.g. Specifying Maven memory parameter without setting MAVEN_OPTS environment variable, Is there a way to pass jvm args via command line to maven?, How to set JVM parameters for Junit Unit Tests?) that touch on this subject but none have the answer I'm looking for.
I want to set the property java.util.logging.config.class to some value but I don't want to set the MAVEN_OPTS environment variable.
I can configure the surefire plugin in my pom file with the property:
<argLine>-Djava.util.logging.config.class=someClass</argLine>
so that it is set every time the test phase is run.
However, if I remove the setting from the pom file and add the following to the command line:
mvn package -DargLine="java.util.logging.config.class=someClass"
then the following error in the test phase is reported and the build fails:
Error: Could not find or load main class java.util.logging.config.class=someClass
If I run the following from the command line:
mvn package -Djava.util.logging.config.class=someClass
then the following error is reported at the beginning of the build but the build and tests are successful:
Logging configuration class "someClass" failed
java.lang.ClassNotFoundException: someClass
I don't really understand the behaviour. Can someone enlighten me?
Yes, you should have
mvn package -DargLine="-Djava.util.logging.config.class=someClass"
Notice the addition of -D inside the argLine.
Let's explain why. argLine is indeed an attribute of the maven-surefire-plugin with the corresponding user property argLine. This means that you can set this property directly on the command line with -DargLine. But then, the value of that property is -Djava.util.logging.config.class=someClass. This is exactly what you had when you configured the plugin in the POM directly with
<argLine>-Djava.util.logging.config.class=someClass</argLine>
Additionally, when you call
mvn package -Djava.util.logging.config.class=someClass
then you are not setting the argLine property. You are adding a system property.
Regarding your approach to configuring tests
If you want to pass in configuration to your tests, use for example a file in src/test/resources/myTestConfig.xml. Or use the enhanced features of Test-ng. Your tests will have no value on the centralized build server, or those who want to run/test your code, where config values can't be changed (easily).
The recommended usage of command-line arguments for Maven is for configuring the Maven plugins, build environment and Java config for the build.
Use as little features, config and plugins as possible. Or you'll face a ton of issues down the line, and the tweak-all-you-want-A-standardized-build-doesn't-mean-sh*t-for-me-Gradle will feel more comfortable.
Related
I am making an app that requires an argument from the command line using Spring Boot, the passed argument then will be passed on to a field as follow:
#Value("#{new java.text.SimpleDateFormat('dd-MM-yyyy').parse('${param.date}')}")
private Date date;
However, when I tried to create the Jar file using the command mvnw package, the following error is shown:
java.lang.IllegalArgumentException: Could not resolve placeholder 'param.date' in value "#{new java.text.SimpleDateFormat('dd-MM-yyyy').parse('${param.date}')}"
How can I tell the compiler that the aforementioned field is from an argument? And, if the jar is made then, how do I inject the field when running the jar using command line arguments?
Thank you!
I cannot reproduce it. Try this:
java -jar [target].jar --param.date=01-11-2021
If tests failing, try #SpringBootTest(args = "--param.date=01-11-2021").
(sample code)
Refs:
7.2.1. Accessing Command Line Properties
By default, SpringApplication converts any command line option arguments (that is, arguments starting with --, such as --server.port=9000) to a property and adds them to the Spring Environment.
7.26.3. Testing Spring Boot Applications > Using Application Arguments
The command mvnw package was failed because of the spring unit test. I just had to skip the unit test using the -Dmaven.test.skip=true parameter. So, the complete command would be mvnw package -Dmaven.test.skip=true. As for on how to run the .jar with the parameters once the jar is created, can be seen in DEWA Kazuyuki - 出羽和之
's answer.
I need to tune the JVM memory by help of Gradle. I've writen settings in the gradle.properties file:
org.gradle.jvmargs=-XX:MaxMetaspaceSize=60M
but it didn't work. Then I've done it manually in an IDEA (Run>Edit Configurations...) and wrote the settings for the needed class (in VM options: field) and it works. Can we do the same by help of Gradle?
I've tried to do:
org.gradle.jvmargs=-XX:MaxMetaspaceSize=60M test1.Test
but I got the error:
Error: Could not find or load main class test1.Test
When you run your application via IDEa, it runs the application using java ... command and gradle is not involed at all, so whatever you put in build.gradle doesn't matter.
If you want to run your app via gradle, consider using application plugin, which allows you to set jvm args. If you use Spring Boot use can use bootRun task and specify params in jvmArgs property.
We set several key/value pairs in our gradle.properties file. (eg LOGIN_UID, LOGIN_PWD)
We can successfully reference them in our build.gradle (eg $LOGIN_UID) and our JUnit tests (eg System.getProperty("LOGIN_UID") when running gradle test from the cmdline.
However when clicking on a Run Test codelens within a JUnit's Java file within VSCode gradle.properties are not passed in. Guessing the Gradle test task is not being executed?
Greatly appreciate it if someone can help us understand and solve this running from a codelens.
Basically what you need is to add a setting in VS Code, something like this:
{
"java.test.config": {
"vmArgs": ["-DLOGIN_UID=id", ...]
}
}
Then test runner will pick up them and pass the properties to JVM.
At last, the configuration can be persisted in your workspace's .vscode/settings.json. If the properties have any sensitive data, like password, don't commit them to the source control!
After cloning jamm and setting the maven URL in the build.xml to https://repo1.maven.org/maven2/org/apache/ivy/ivy, I was able to install it with ant jar. Now I'm trying to use MemoryMeter in my project code.
The official GitHub README says: 'To use MemoryMeter, start the JVM with "-javaagent:/jamm.jar"'.
Following this advice and using a javaagent for the first time in my life (in a Grails 2.5.6 project) I've set the following in my IDEA IntelliJ run configuration:
in VM options: -javaagent:"/home/myusername/git/laser-ygor/lib/jamm-0.3.4-SNAPSHOT.jar"
in Command line: -noreloading -javaagent:"/home/myusername/git/laser-ygor/lib/jamm-0.3.4-SNAPSHOT.jar" run-app
I think one of those two javaagent settings should be obsolete, but I don't know which of them works, and I believe it won't do any harm to set them both.
Anyway, I'm experiencing: Instrumentation is not set; Jamm must be set as -javaagent.
which obviously is caused by instrumentation being null.
So, how can I use this javaagent with instrumentation being not null?
When using Netbeans, running a file/class inside a Maven project means that Netbeans executes something like "mvn exec:exec ...".
Now I want to access the maven sys prop ${basedir} from within the executed class. How do I do that? Setting a command line in pom.xml overwrites the command line from Netbeans and therefore does not work. Using exec:java together with the exec-maven-plugin's sys props configuration section does not work either because I'm using a special class (re-)loader that only works with exec:exec (somehow project dependency classes cannot be found by it because the default loader seems to be different).
Any ideas?
Adding -Dbasedir=${basedir} to the exec.args parameter works:
exec.args=-classpath %classpath -Dbasedir=${basedir} ${packageClassName}
Netbeans does not know about that variable, so it looks like the exec-maven-plugin evaluates that string.