Specifying Maven memory parameter without setting MAVEN_OPTS environment variable - maven

I was wondering if it is possible to specify Maven memory boundaries with a syntax similar to:
mvn -Dtest=FooTest -DXmx=512M clean test
I tried a couple of variations till now, unsuccessfully.
I am aware of MAVEN_OPTS environment variable, but I would like to avoid that.
Related to the above question, it would be nice to know if there is the possibility to specify the memory behavior of the surefire plugin in a similar manner, so that it forks the jvm using the overridden memory amount (eventually overriding the <argLine> parameter in the pom plugin configuration, if present)

To specify the max memory (not via MAVEN_OPTS as originally requested) you can do the following:
mvn clean install -DargLine="-Xmx1524m"

You can configure the surefire-plugin to use more memory. Take a look on
Strange Maven out of memory error.
Update:
If you would like to set the parameter from command-line take a look on {{mvn.bat}} (or {{mvn}} shell script) in your maven installation directory. It uses with additional options specified in command line.
Next possibility is to set surefire-plugin and use properties specified in command-line, e.g. mvn ... -Dram=512
and
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<forkMode>once</forkMode>
<argLine>-Xms${ram}m -Xmx${ram}m</argLine>
</configuration>
</plugin>

Since Maven 3.3.1 a default can also be specified in ${maven.projectBasedir}/.mvn/jvm.config
It is documented here: https://maven.apache.org/docs/3.3.1/release-notes.html#JVM_and_Command_Line_Options

Related

Can I set DYLD_LIBRARY_PATH with maven-surefire-plugin?

In a Java project, I depend on a third-party native library that in turn loads dependency dylibs via DYLD_LIBRARY_PATH. I've successfully run tests via Tycho's surefire plugin by setting this with the environmentVariables property of the plugin config, but a similar setup in a non-OSGi project leaves the DYLD_LIBRARY_PATH variable unset.
Here's a snippet of my functioning Tycho configuration:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>0.25.0</version>
<configuration>
<argLine>-Dfile.encoding=UTF-8 -Djava.library.path="${dylib-program}"</argLine>
<environmentVariables>
<DYLD_LIBRARY_PATH>${dylib-program}</DYLD_LIBRARY_PATH>
</environmentVariables>
</configuration>
</plugin>
With that, the tests run correctly, and outputting System.getenv("DYLD_LIBRARY_PATH") shows the set path.
Here's the equivalent snippet from my non-Tycho config:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF-8 -Djava.library.path="${dylib-program}"</argLine>
<environmentVariables>
<DYLD_LIBRARY_PATH>${dylib-program}</DYLD_LIBRARY_PATH>
<OtherVar>bar</OtherVar>
</environmentVariables>
</configuration>
</plugin>
When I run this, however, the dependency library doesn't load properly and System.getenv("DYLD_LIBRARY_PATH") returns null. System.getenv("OtherVar"), however, returns "bar", so setting environment variables generally seems to work. That makes me suspect that there's something peculiar about DYLD_LIBRARY_PATH (and the same happened with LD_LIBRARY_PATH, but not PATH).
The behavior is the same when run in Eclipse (either as-is or with the path also set in the Run Configuration environment) and via the command line (again either as-is or with the environment variable explicitly exported before the run). The Tycho and non-Tycho projects are run on the same machine, with the same tools (other than the test plugins). I'm using macOS 10.12.3, Java 1.8.0_111, and Maven 3.3.9.
Is there a general limitation about setting this property, at least on a Mac, or is there a way I can work around this?

How do I configure my Maven-war-plugin's useCache feature so that consecutive builds are faster?

I’m using Maven 3.3.0 on Mac Yosemite. I wanted to make use of the maven-war-plugin’s useCache feature, but it isn’t doing anything in my multi-module project. When I run
mvn clean install -DskipTests
my project takes about 1:25 to run with the below configuration
<profile>
<id>prepare-deploy-war-to-jboss</id>
<activation>
<file>
<exists>${basedir}/src/main/webapp</exists>
</file>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<useCache>true</useCache>
<cacheFile>/tmp/${project.artifactId}/war/work</cacheFile>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Then I run the same command again and the project takes the same amount of time. I can see “work” files getting created so the plugin is definitely running but consecutive builds do not seem to be doing anything.
My question here isn’t so much as why isn’t useCache speeding up my build, but how can I configure my plugin differently so that consecutive runs do speed up the build? If there is another plugin I should be using that would speed up builds on back-to-back runs, then that would also suffice here.
Looking at the WAR mojo code (at the time of writing), the cache is mainly used by its web app structure concerning overlays management, so in most of the cases it would not improve build time indeed.
Moreover, as stated by its official documentation, the cache mechanism is an experimental feature, hence disabled by default, which probably doesn't achieve (yet) user expectations.
Regardless of the effectiveness of this cache option, some hints to speed up maven builds could be:
Consider whether you really need to clean at each and every run
Consider building offline (-o option) if everything you need is already on your local cache
Consider using threads during your build (-T option)
Consider going on quite mode (-q option), swithing off build log temporarely and getting only error logs (basically: no news, good news)
In your case, the War Plugin is activated upon the existence of a structure typical of a war packaging, which probably means this profile is part of the aggregator/parent pom and then activated only on the war module. Although it might impact very little, also consider moving the War Plugin configuration to its concerned module and avoid such a triggered configuration
Last but not least, during development time, build time is probably more important than war size, so you could switch off the default mechanism of re-compressing external libraries added to the war file, via the recompressZippedFiles option:
Indicates if zip archives (jar,zip etc) being added to the war should be compressed again. Compressing again can result in smaller archive size, but gives noticeably longer execution time.
Default: true
So a sample configuration would look like:
<properties>
<war.recompress.files>false</war.recompress.files>
</properties>
<build>
<finalName>webapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<recompressZippedFiles>${war.recompress.files}</recompressZippedFiles>
</configuration>
</plugin>
</plugins>
</build>
Note: since there is no user property for this configuration entry, I also added a property for it, to switch it on/off on demand via command line (or via profile).
You could then test the different execution times executing the default build (with the configuration above disabling recompression) against the previous configuration (below, switching recompression on for the current execution, on demand):
mvn clean install -Dwar.recompress.files=true
You may then consider to profile it to switch it on/off depending on development phase.

How can I specify complex Maven configuration options on the command line?

For example, I want to use the Wildfly deploy plugin, as outlined here:
http://docs.jboss.org/wildfly/plugins/maven/latest/deploy-artifact-mojo.html
To deploy, I would use a command like mvn wildfly:deploy -Dfilename=my.ear. But let's say I want to deploy to a particular server group. Using a POM, I would add:
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.1.0.Alpha1</version>
<configuration>
<domain>
<server-groups>
<server-group>main-server-group</server-group>
</server-groups>
</domain>
</configuration>
</plugin>
But if I can't change the POM, how would I pass this configuration in on the CLI or in $HOME\.m2\settings.xml?
The usage page indicates a configuration "type" of org.wildfly.plugin.deployment.domain.Domain for a "domain" option but I don't know how to type those options out on the CLI. Obvious answers like -Ddomain.server-groups.server-group=my-server-group don't seem to work.
If you could change the pom using a property like <server-group>${server.group}</server-group> should work. I don't think maven has support for complex attribute properties like that.
If that's not possible you could file a feature request.
Not exactly the answer to the overall question, but to your specific problem.
Changing the version in the pom to 1.2.2.Final, you can now do:
-Dwildfly.serverGroups=main-server-group
which I guess wasn’t available in 1.1.0.

Maven: Let "mvn -Pjenkins" be the same as "mvn clean install pmd:pmd javadoc:aggregate"

We have a number of Maven jobs in our Jenkins instance, each with their own particular invocation string specified in the build configuration similar to
mvn clean install -DDISABLED="javadoc:aggregate" checkstyle:checkstyle pmd:pmd findbugs:findbugs
I would like to consolidate this so that the invocation string is stored somewhere in the POM along with suitable profile information so we can replace the invocation strings of all these slightly different jobs with a
mvn -Pjenkins
standard invocation. To my understanding the defaultGoal entry only supports a single goal which on first glance seems to be insufficient for representing our multiple goals, but might be enough if we can make it correspond to multiple entries instead. If at all possible I would like avoid setting up profile specific bindings to standard lifecycle phases if a simple invocation string will do.
You can configure additional mojos ina profile, and you can bind mojos to life cycle phases. These two things combined will allow you to run additional mojos when a certain profile is given.
This is a standard techniqued used throughout in Maven. For example, when you run "mvn release:perform", it runs a nested Maven session with "-Prelease" that does additional things, such as GPG-signing binaries.
<profile>
<id>jenkins</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>findbugs</goal>
</goals>
</execution>
</executions>
</plugin>
... other mojos ...
The findbugs mojo is bound by default to the compile phase, so this gets invoked automatically at the compilation phase. If you want to use a mojo that doesn't bind to any lifecycle phase by default, you add <phase>...</phase>.
See our POM in the Jenkins core for a complete example where we invoke FindBugs. The other mojos are the basically the same.
Note that for this to work, your default goal needs to invoke the life cycle phase to the certain point (say package or install.)
I don't think there's a direct way to give Maven an invocation string. As you say, you can add a custom 'jenkins' profile in which you configure the checkstyle, pmd, and findbugs plugins to be bound to a build phase (e.g. their default phase). You would still need to run mvn -Pjenkins clean install though. However this has the advantage that you can also add custom config to those plugins (e.g. to include test code in the PMD coverage).
I think you can add the settings for the checkstyle, pmd, findbugs and javadoc plugins in a profile's <build><plugins/></build> section along with a <properties> bit where you can define the javadoc property. Also, add an explicit invocation of the maven-clean-plugin attached to the clean phase. Then just invoke the build like:
mvn -Pjenkins site:site
You could even set the defaultGoal to site, if you like.

Maven: How to pass command-line arguments from release:perform to deploy?

When I invoke release:peform on my project. it invokes deploy which in-turn invokes gpg. I'd like to pass the gpg passphrase into the process using a system property or environment variable but neither seems to work.
If I invoke mvn.bat '-Darguments="-Dgpg_passphrase=test"' -Pwindows-i386-msvc-debug -DconnectionUrl=scm:hg:https://boost-maven-project.googlecode.com/hg/ release:perform Maven ends up invoking:
cmd.exe /X /C mvn deploy --no-plugin-updates -Psonatype-oss-release -P windows-i386-msvc-debug,always-active -f pom.xml"
And as you can see, neither environment variables nor the -Darguments command-line arguments are passed to the deploy goal. Any ideas?
You have configured as -Denv.gpg_passphrase=test, Please correct me, if I'm wrong. I understand that you are trying to pass the environment variable which is not allowed here. it is a system properties named env.gpg_passphrase instead. The -D is always the system properties.
If you would like to use the environment variable, please configure through the OS configuration instead. If you would like to use the system properties please use -D. Please do not mix these two types.
IMHO, I've a scenario as your mentioning to sign the artifact as well. I configure by specifying the "maven-release-plugin" explicitly at the build section as the following example.
<build>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>${my.maven.release.version}</version>
<configuration>
<arguments>${my.release.arguments}</arguments>
</configuration>
</plugin>
<plugins>
</build>
I also configure the properties named my.release.arguments at each developer settings.xml for security purpose (do not share the secret, e.g. user/password/private key,etc.). I am able like to know and identify who releases these artifacts by looking at the signature.
I hope this may help.
Regards,
Charlee Ch.
It turns out this is caused by a Sonatype bug: https://issues.sonatype.org/browse/CENTRALSRV-35

Resources