How to integrate Spring Instrument javaagent in ALL JUnit tests - java

I am writing unit tests on a large project which I need to pass JVM arguments to, those are my JVM arguments built into the Eclipse run configuration for that project :
--module-path lib/javafx-sdk-13.0.2/lib --add-modules=javafx.controls
-javaagent:lib/aspectjweaver-1.9.5.jar
-javaagent:lib/spring-instrument-5.2.3.RELEASE.jar
My issue is that I need to add those arguments for EVERY JUnit test or testing sequence. Is there a better approach for this? Some way to not have to add those arguments manually into every new test I create?
******EDIT******
This also has the nasty side-effect of not letting me build this project at all! Maven does not use my custom JUnit run config for running the entire set of tests for the application (which works fine because I set the JVM arguments in there) but rather its own which obviously fails because the arguments are not there. That is a huge problem, is there a way to "hardcode" those JVM arguments directly into the POM somehow?
******EDIT 2******
This is my Spring-Boot-Maven-Plugin config in my POM.xml file :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArguments>
--module-path lib/javafx-sdk-13.0.2/lib
--add-modules=javafx.controls
-javaagent:lib/aspectjweaver-1.9.5.jar
-javaagent:lib/spring-instrument-5.2.3.RELEASE.jar
</jvmArguments>
</configuration>
</plugin>
******SOLUTION******
Adding the Maven Surefire plugin and setting it up this way fixed the issue :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<argLine>
--module-path lib/javafx-sdk-13.0.2/lib
--add-modules=javafx.controls
-javaagent:lib/aspectjweaver-1.9.5.jar
-javaagent:lib/spring-instrument-5.2.3.RELEASE.jar
</argLine>
</configuration>
</plugin>
Thanks!

You can set the jvm args in the surefire plugin. Use mvn test to run tests. Something like
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<argLine>-Djava.security.policy=${basedir}/src/test/resources/java.policy</argLine>
</configuration>
</plugin>
</plugins>
More here http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#argLine

Related

Maven command runs fine on local machine, but not in Jenkins

So I have a maven project that has a profile
When I run the following in the terminal for my project, the tests will run just fine
mvn clean install -Pserial-integration-test -Dcucumber.options="--tags #'QR_Scan'" -Dtest.environment=PrePRod
When I run the following in a Jenkins project it will not run the tests that I need it too
clean install -Pserial-integration-test -Dcucumber.options="--tags #'QR_Scan'" -Dtest.environment=PrePRod
Jenkins settings
I have setup a Jenkins Maven project and told Jenkins where my Pom is, and I send the command below for the goal and options "clean install -Pserial-integration-test -Dcucumber.options="--tags #'QR_Scan'" -Dtest.environment=PrePRod"
Maven Settings
serial-integration-test
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<junitPlatformArtifactName>com.github.junit-team.junit5:junit-platform-engine</junitPlatformArtifactName>
<forkCount>1</forkCount>
<reuseForks>true</reuseForks>
<includes>
<include>**/Parallel*IT.class</include>
</includes>
<systemPropertyVariables>
<test.environment></test.environment>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>5.0.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>validate</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<plugins>
<plugin>
<name>com.gm.onstar.rita.cucumber.CucumberReporter</name>
</plugin>
</plugins>
<glue>
<package>com.gm.onstar.rita.stepdefinitions</package>
</glue>
<featuresDirectory>src/main/resources/features</featuresDirectory>
<tags>
<tag>${cucumber.tag1}</tag>
<tag>${cucumber.tag2}</tag>
<tag>${cucumber.tag3}</tag>
<tag>${cucumber.tag4}</tag>
<tag>${cucumber.tag5}</tag>
<tag>~#Ignore</tag>
</tags>
</configuration>
</execution>
</executions>
</plugin>
What I have tried
I have tried putting in like this in Jenkins -Dcucumber.options="--tags #QR_Scan" and like this -Dcucumber.options='--tags #QR_Scan'
I have tried putting the profile -Pserial-integration-test with a space and without a space -P serial-integration-test
I have tried to see if I a missing some sort of plugin
I have tried to see if Mvn clean install or Mvn clear verify would run it on Jenkins
What it might be.
Jenkins does not like that my cucumber runner is in the main and not in java test folder?
Am I missing a plugin for Jenkins?
Am I typing the command in wrong in jenkins, and maybe missing some parentheses or something?
Any help would be appreciated. Thank you!

How to pass --illegal-access JVM argument to spring boot maven plugin

I have an application that runs just fine when running this from the command prompt :
java -jar --illegal-access=permit target/Something.jar
However, configuring my spring boot maven plugin in my pom.xml as such gives me the same error as if I ran my cmd without the illegal-access=permit part, telling me it is being ignored :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.something.PreMain</mainClass>
<jvmArguments>
--illegal-access=permit
</jvmArguments>
</configuration>
</plugin>
What am I doing wrong? This app worked perfectly in java 14 and I'm in the process of upgrading to java 16. Everything still works perfectly except intelliJ not being able to launch it in debug mode due to the missing illegal-access=permit JVM argument.
If you're trying to run the application in IntelliJ, you don't need to pass anything into Maven. In IntelliJ, open the run configuration for your app and under Environment->VM options add --illegal-access=permit. See the attached image, Main class would be your fully qualified location of your #SpringBootApplication class, e.g. com.something.MySpringBootApplication
When you start your app in debug mode in IntelliJ, you'll see something like
/Library/Java/JavaVirtualMachines/jdk-16.0.2.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:52737,suspend=y,server=n --illegal-access=permit -XX:TieredStopAtLevel=1..., notice the argument getting passed to your app.
You may want to try putting it in the properties instead. Try this:
<properties>
<jvm.options>--illegal-access=permit</jvm.options>
</properties>
Then use it in the plugin as follows:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.something.PreMain</mainClass>
<compilerArgs>
<arg>${jvm.options}</arg>
</compilerArgs>
</configuration>
Note: Instead of args, you would need to use argline if you're accessing illegal-access parameter for surefire.

spring-boot-maven-plugin doesn't create fat jar

I'm using spring-boot-maven-plugin to package my REST service. I'm building the jar using mvn clean install or mvn clean package. After I decompile the jar, I don't find any of the dependencies added (I was expecting it to be a fat jar with all dependencies)
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.9.RELEASE</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
<finalName>myapp</finalName>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
When I run the spring boot using java -jar myapp.jar -Drun.jvmArguments="-Dspring.profiles.active=qal" I'm getting ClassNotFoundException for many of the classes. It's clear that artifact didn't build as expected. However, if I start spring boot application using maven ./mvnw spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=qal" I guess, it finds all the dependencies in target folder hence works fine. How can I fix the build issue so that I can start app using java -jar command.
EDIT: It's multi-module maven project
it seems you are using a wrong command. mvn clean package is maven command, you should use command 'repackage', it used for
Repackages existing JAR and WAR archives so that they can be executed
from the command line using java -jar
as it mentioned here https://docs.spring.io/spring-boot/docs/current/maven-plugin/repackage-mojo.html
Or probably it's plugin configuration issue. Just checked: it works with spring-boot-maven-plugin-2.0.0.RELEASE
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
Use this one
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
<executable>true</executable>
<fork>true</fork>
<!-- Enable the line below to have remote debugging of your application on port 5005
<jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments>
-->
</configuration>
</plugin>

how do you write a Maven script that calls a Jar file after the code in the project is packaged?

The idea is to run "mvn package", as usual, and after all the steps are done, a Jar utility should be called passing the filepath of the packaged code (a jar or a war file) as an argument.
The utility would be called as follows from the command line:
java -jar Utility.jar -filepath {path of the new jar/war file}
I want to integrate that final step to the build process. How do I modify the pom.xml file in order to accomplish this?
have a look at the maven exec plugin. you can bind an execution of it to the package phase (would run after the built-in bindings defined by the packaging) to run java (the executable) with the arguments "-jar Utility.jar -filepath ${project.build.directory}/${project.artifactId}-${project.version}-${project.packaging}"
the result would look kinda like this:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>run jar utility</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>Utility.jar</argument>
<argument>-filepath</argument>
<argument>${project.build.directory}/${project.build.finalName}.${project.packaging}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
though this invocation would be platform specific. you could improve on this a bit and use "java" instead of "exec" (you'd need to provide the main class name in that Utility.jar)
if you describe what the utility you plan on using does there might be a more cross-platform way to do it (for example the maven antrun plugin)
Here's an alternative way to run the exec-maven-plugin from what #radai suggested. If you can do it this way instead, I recommend it.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<inherited>false</inherited>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<!--I don't want my project's dependencies in the classpath-->
<includeProjectDependencies>false</includeProjectDependencies>
<!--Just include the dependencies that this plugin needs. IE: the Utility dependencies-->
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>com.utility</groupId>
<artifactId>Utility</artifactId>
</executableDependency>
<mainClass>com.utility.MyMainClass</mainClass>
<!--You may be able to use a variable substitution for pathToJarFile. Try it and see-->
<commandlineArgs>-filepath pathToJarFile</commandlineArgs>
</configuration>
<dependencies>
<dependency>
<groupId>com.utility</groupId>
<artifactId>Utility</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>

Maven: plugin to fail a build if a string is found

During development, I have an habit of wrapping code that should not be in production inside "TODEL" tag. For example:
//TODEL - START
//used to test the crashing behavior
String s = null;
int i = s.length;
//TODEL - END
Is there a maven plugin that can fail a build in jenkins if I accidentally checkin a file that contains "TODEL"?
One thing you can do is to use maven checkstyle plugin . You can set up a rule and the make the build fail if it is not compliant to those rules.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>my-checkstyle.xml</configLocation>
</configuration>
</plugin>
The configuration property maven.checkstyle.fail.on.violation.
Then mvn checkstyle:check. Or configure it to execute in a phase of your choice (compile or process-resources) by adding to the plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<executions>
<execution>
<id>TODEL</id>
<configuration>
<configLocation>my-checkstyle.xml</configLocation>
</configuration>
<goals>
<goal>check</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
More info: http://maven.apache.org/plugins/maven-checkstyle-plugin

Categories