Properly pass JDK argument into Maven pom file - java

Because I need to customize Host header in HTTP request, I need to start my Spring Boot Java app with following argument (available since JDK 12):
java -jar -Djdk.httpclient.allowRestrictedHeaders=host application.jar
but how to pass it into maven pom.xml file to be able to use this argument durring tests which are failing because of missing this flag?
I tried to use maven-compiler-plugin in following way:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-Djdk.httpclient.allowRestrictedHeaders=host</arg>
</compilerArgs>
</configuration>
</plugin>
but it's wrong:
error: invalid flag: -Djdk.httpclient.allowRestrictedHeaders=host
Following examples are not working either:
-jdk.httpclient.allowRestrictedHeaders=host
jdk.httpclient.allowRestrictedHeaders=host
So i tried even with spring-boot-maven-plugin
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-Djdk.httpclient.allowRestrictedHeaders=host</jvmArguments>
</configuration>
</plugin>
but it's also not working because in that case this flag is ignored and I got restriction error when I run mvn test. Which is not happening when I run java with this flag.

You seem to be configuring the wrong plugin. You said you need to "be able to use this argument during tests" which means you should be configuring Maven Surefire Plugin.
Have a look at the example they have provided. May be you can use systemProperties:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<systemProperties>
<property>
<name>propertyName</name>
<value>propertyValue</value>
</property>
[...]
</systemProperties>
</configuration>
</plugin>
or the argLine approach:
<argLine>-Djava.endorsed.dirs=...</argLine>

Related

Adding module export to mvn test execution runtime

Getting this error during tests:
class javax.crypto.JceSecurity (in unnamed module #0x45da40ad) cannot access class jdk.internal.util.StaticProperty (in module java.base) because module java.base does not export jdk.internal.util to unnamed module #0x45da40ad
I've tried creating jvm.config at the root, next to pom.xml as such
--add-modules ALL-SYSTEM
--add-opens java.base/jdk.internal.util=ALL-UNNAMED
--illegal-access=permit
That doesn't change anything.
So i try to configure maven compiler plugin as such:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<fork>true</fork>
<compilerArgs>
<arg>--add-modules</arg>
<arg>ALL-SYSTEM</arg>
<arg>--add-opens</arg>
<arg>java.base/jdk.internal.util=ALL-UNNAMED</arg>
</compilerArgs>
<argLine>
--add-modules ALL-SYSTEM
--add-opens java.base/jdk.internal.util=ALL-UNNAMED
--illegal-access=permit
</argLine>
<source>${java.compiler.source}</source>
<target>${java.compiler.target}</target>
</configuration>
</plugin>
for the record i even tried it so:
<argLine>
--add-modules ALL-SYSTEM
--add-opens java.base/jdk.internal.util=ALL-UNNAMED
--illegal-access=permit
</argLine>
Nothing. Then i tried surefire plugin like so :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<forkCount>0</forkCount>
<argLine>
--add-modules ALL-SYSTEM
--add-opens java.base/jdk.internal.util=ALL-UNNAMED
--illegal-access=permit
</argLine>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
Two days working on this and failing miserably. Please help. Using OpenJdk11
I cross checked with surefire 3.0.0-M3 and -M5 and it should be absolutely sufficient to configure surefire with add-opens Oracle's Migration Guide
Also your format is absolutely correct: --add-opens <module>/<package>=ALL-UNNAMED. In Combination with --illegal-access=permit it should work fine.
I see only one more option: remove =ALL-UNNAMED from your opens-argument, this will crash the VM/ Surefire and proves your settings are active.
Beyond that your test classes ought to be invoked through reflection by your favorite runner (test method package private/ without public-modifier). This requires the same opens-declaration for your test classes/ cause the same issues – unless the Maven project isn't a module itself.
Maybe clarify this in your question.
Many tutorials and guides publish the following workaround
<forkCount>0</forkCount>
Please do not use it!
The surefire subprocess is A MUST especially in JPMS.
Please do not apply the workaround with forkCount=0 and rather report a bug in the Apache JIRA and communicate with the open source developers.
Thank to the other answers, it helped me to dig deeper. I managed to solve it with the following changes in pom
<properties>
<!-- Must be in pom's properties section. <sonar.jacoco.reportPaths>target/coverage.exec</sonar.jacoco.reportPaths> -->
<jacoco.version>0.7.7.201606060606</jacoco.version>
<!-- Used by surefire plugin run tests with openjdk11 -->
<argLine>--add-modules java.base --add-opens java.base/jdk.internal.util=ALL-UNNAMED --illegal-access=permit</argLine>
</properties>
.........
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.compiler.source}</source>
<target>${java.compiler.target}</target>
</configuration>
</plugin>
........
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
Basically i had to put the argline in properties. Compiler doesn't seem to need it because it's not picking it up from there. But surefire does, it's reading the argline from maven's properties.

maven: Some input files use unchecked or unsafe operations [duplicate]

In NetBeans 7.2, I'm having trouble finding how to compile using -Xlint:unchecked in a Maven project. Under an Ant project, you can change compiler flags by going to Project Properties -> Compiling, but Maven projects don't seem to have any such option.
Is there any way to configure the IDE to compile with such flags using Maven?
I guess you can set compiler arguments in your pom.xml. Please refer this http://maven.apache.org/plugins/maven-compiler-plugin/examples/pass-compiler-arguments.html
<compilerArgument>-Xlint:unchecked</compilerArgument>
I want to elaborate on #Nishant's answer. The compilerArgument tag needs to go inside plugin/configuration tag. Here is a full example:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<testSource>1.8</testSource>
<testTarget>1.8</testTarget>
<compilerArgument>-Xlint:unchecked</compilerArgument>
</configuration>
</plugin>
</plugins>
This works for me...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
<compilerArgs>
<arg>-Xlint:unchecked</arg> <-------this right here ---->
</compilerArgs>
</configuration>
</plugin>
</plugins>
The pom file information is spot on. I had the additional challenge of building someone else's Maven project in Jenkins and not having access to the pom file repository.
I created a pre-build step to insert the compiler parameter into the pom file after downloading it from git, for example
sed -i 's|/target> *$|/target>\n<compilerArgument>\n-Xlint:deprecation\n</compilerArgument>|' $WORKSPACE/pom.xml

Append the value of argLine param in maven-surefire-plugin

I am using maven-surefire-plugin + Sonar together and I would like to add some extra value to argLine parameter of the maven-surefire-plugin.
So I did it:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<argLine>-DCRR.Webservice.isSimulated=true -D...</argLine>
</configuration>
</plugin>
...
</plugins>
</build>
But in this case I am overwriting the original value of the argLine parameter and Sonar does not generate jacoco.exec file.
I can see in the maven debug log (-X) that the value of argLine param without overwriting its value is -javaagent:/opt/jenkins/.../myproject-SONAR/.repository/org/jacoco/org.jacoco.agent/0.7.4.201502262128/org.jacoco.agent-0.7.4.201502262128-runtime.jar=destfile=/opt/jenkins/.../myproject-SONAR/target/jacoco.exec.
What is the proper way to APPEND the original value of this parameter (keep the original + add extra values)?
I am using Apache Maven 3.5.0, Java version: 1.8.0_131, vendor: Oracle Corporation.
The official documentation calls that late replacement.
If you do the following you will overwrite the value of the argLine parameter which is set by another plugins before, so DO NOT DO THIS:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-D... -D...</argLine>
</configuration>
</plugin>
The proper way to keep the existing values and add your configuration is to use #{...} syntax:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>#{argLine} -D... -D...</argLine>
</configuration>
</plugin>
OR you can set argLine as a property in your pom.xml file:
<properties>
<argLine>-DCRR.Webservice.isSimulated=true -D...</argLine>
</properties>
Both solutions above works properly.
Update for Apache Maven 3.8.3.
In my case only combination of both #zapee suggestions works, in other words it's important to add <argLine/> to <properties> and #{argLine} to configuration section. Example:
<properties>
<!-- This is required for later correct replacement of argline -->
<argLine/>
</properties>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>#{argLine} -D... -D...</argLine>
</configuration>
</plugin>
Hope, it helps somebody.
Thanks!
In my case it was:
<argLine>${tycho.testArgLine} -D...</argLine>

Unable to pass java compiler parameters using maven

As the title says I am unable to pass command line parameters to the java compiler using maven, I am using the maven-compiler-plugin to do it, and accordingly to this (specifically for the compilerArgs option of the pluging) I am using the "latest way" to speficy the arguments passed to the compiler. Well enough talk, more code, this is my maven configuration for the plug-in and I am not sure what am I doing wrong:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<fork>true</fork>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
I am following the instructions for the usage of the tool which says that <fork> have to be set to true, and I do not know what am I missing... a little bit of help please?
May or may not be helpful to mention that: I need the parameters argument as specified here because I want to get the name of the arguments in my methods in runtime using reflection; I use the -X argument when calling maven to see the debug and I shows me the "fork" call that it does and I cannot se ANYWHERE the arguments I am passing (maybe I need to enable the plug-in; but I think In this case is automatically enabled since it is not part of any profile, I am not a maven expert so please correct me if I am wrong).
EDIT: I have tried in several ways with and without the dash I have even tried the "old way" to do it:
<compilerArguments>
<parameters />
</compilerArguments>
And:
<compilerArgument>-parameters</compilerArgument>
My mistake: I created the code before modifying my pom file, and ran it using maven to check that is was actually working. After that, I modified my pom to include the -parameters flag. The code had already been compiled without that flag and was not modified after. Therefore, maven saw no changes in the code and did not recompile the file.
SOLUTION execute a mvn clean, delete the compiled classes, delete the target folder, or whatever is necessary to ensure that the files are recompiled.
Please mention, that you always have to write a '-' letter before
the parameters.
Below you can see a configuration for your plugin with some sample
compiler arguments.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<fork>true</fork>
<compilerArgs>
<arg>-verbose</arg>
<arg>-Xlint:all,-options,-path</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
From the maven compile plugin main page:
The Compiler Plugin is used to compile the sources of your project. Since 3.0, the default compiler is javax.tools.JavaCompiler (if you are using java 1.6) and is used to compile Java sources. If you want to force the plugin using javac, you must configure the plugin option forceJavacCompilerUse.
I'm guessing the javax.tools.JavaCompiler doesn't works the same way javac does with the -parameters option.
Try forcing the javac use
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<forceJavacCompilerUse>true</forceJavacCompilerUse>
<fork>true</fork>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>

"The command line is too long" -- when running maven test

Running $mvn test on a 64-bit Windows gives me the following error, even if I do $mvn test -Dgwt.genParam=false:
The command line is too long
Make sure you are using version 2.16 and that you have the useManifestOnlyJar option (as documented here).
For example:
<project>
[...]
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<useManifestOnlyJar>true</useManifestOnlyJar>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
[...]
</project>
This will create jar with a manifest that re-creates your classpath (as opposed to setting it via the CLASSPATH variable which is an approach that is affected by Windows' command-line limit problem).

Categories