How to set VM arguments for Jetty run from maven-jetty-plugin?
For example, I need to pass -Xmx arguments to Jetty run by the mvn jetty:run command.
The enviroment variable MAVEN_OPTS is the answer. The string content of MAVEN_OPTS is passed to JVM (java.exe).
Linux: in shell type export MAVEN_OPTS=....
Windows: in shell (cmd.exe) type set MAVEN_OPTS=...
For example: on Windows set MAVEN_OPTS="-Xmx1024m" sets the heap size of the Maven process to 1024mb.
Update (01.04.2013): Pass it directly to Jetty.
Matthew Farwell (please upvote his answer to give him credit) comes with the solution of using a forked JVM process to run Jetty which is a new feature of the Jetty plugin. This is a better solution as the former runs inside same JVM process as Maven (thus shares memory).
With more recent versions of the maven-jetty-plugin, you can use mvn:run-forked. The option jvmArgs will allow you to set -Xmx etc.
For more information, see: jetty:run-forked : Running an unassembled webapp in a separate jvm.
I think the original issue was Starting Jetty in separate JVM.
It seems like your current approach is correct - when running jetty through maven, jetty is a thread inside the maven process. So increasing maven's heap will increase jetty's heap.
How are you setting MAVEN_OPTS?
One example I found looks like this: MAVEN_OPTS='-Xmx256m -Xms10m' mvn clean jetty:run
Note that MAVEN_OPTS is an environment variable here, and not passed to the JVM (who wouldn't know what to do with it).
To specify vm arguments via the command line (as originally asked) you can do the following:
mvn clean install -DargLine="-Xmx1524m"
The <jvmArgs> param mentioned here : Maven jetty plugin
didn't work for me .
Maven version : Apache Maven 3.0.3
Jetty Maven plugin version : jetty-maven-plugin:8.1.10.v20130312
This worked :
MAVEN_OPTS='-Xmx4096m -Xms4096m'
export MAVEN_OPTS
mvn jetty:run &
On Linux/Unix
export MAVEN_OPTS="-Xmx256m" && mvn clean install jetty:run
will do the trick
The plugin allows you to specify jvmArgs like this:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<jvmArgs>-Xmx1024</jvmArgs>
<scanIntervalSeconds>10</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webAppConfig>
<jettyEnvXml>jetty-env.xml</jettyEnvXml>
</webAppConfig>
</configuration>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run-exploded</goal>
</goals>
</execution>
</executions>
</plugin>
As referenced in Configuring Apache Maven, discussing the MAVEN_OPTS environment variable referenced in other answers, you can also control project configuration with files in the .mvn directory.
For VM arguments in particular, you can add a .mvn/jvm.config file containing the associated parameters:
Starting with Maven 3.3.1+ you can define JVM configuration via ${maven.projectBasedir}/.mvn/jvm.config file which means you can define the options for your build on a per project base. This file will become part of your project and will be checked in along with your project. So no need anymore for MAVEN_OPTS, .mavenrc files.
you can use to pass -Xmx argument like;
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version></version>
<configuration>
<jvmArgs>-Xmx -Xms -XX:PermSize= -XX:MaxPermSize= -XX:+HeapDumpOnOutOfMemoryError</jvmArgs>
<scanIntervalSeconds>1</scanIntervalSeconds>
<stopKey>stop-jetty</stopKey>
<stopPort>9999</stopPort>
<systemProperties>
<systemProperty>
<name>jetty.port</name>
<value>9090</value>
</systemProperty>
<systemProperty>
<name>spring.profiles.active</name>
<value></value>
</systemProperty>
</systemProperties>
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
There is no way using the commandline. But you could copy the mvn.cmd / mvn.sh to mvnhp.cmd and change the line
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %CLASSWORLDS_JAR% "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
To
%MAVEN_JAVA_EXE% -Xmx1024m %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %CLASSWORLDS_JAR% "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
Related
I am using spring-boot-maven-plugin to build a docker image from my app with this command:
spring-boot::build-image
And I need to change default size of jvm direct memory (default is 10m) with this jvm argument:
-XX:MaxDirectMemorySize=64M
and this is my desperate attempt to do that in pom.xml of app where I was trying everything what came to my mind:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<jvmArguments>-XX:MaxDirectMemorySize=64M</jvmArguments>
<environmentVariables>
<JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=64M</JAVA_TOOL_OPTIONS>
<JAVA_OPTS>-XX:MaxDirectMemorySize=64M</JAVA_OPTS>
</environmentVariables>
<systemPropertyVariables>
<JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=64M</JAVA_TOOL_OPTIONS>
<JAVA_OPTS>-XX:MaxDirectMemorySize=64M</JAVA_OPTS>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
<image>
<name>docker.io/example/${project.artifactId}:${project.version}</name>
</image>
<excludeDevtools>true</excludeDevtools>
<systemPropertyVariables>
<JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=64M</JAVA_TOOL_OPTIONS>
<JAVA_OPTS>-XX:MaxDirectMemorySize=64M</JAVA_OPTS>
</systemPropertyVariables>
<environmentVariables>
<JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=64M</JAVA_TOOL_OPTIONS>
<JAVA_OPTS>-XX:MaxDirectMemorySize=64M</JAVA_OPTS>
</environmentVariables>
<jvmArguments>-XX:MaxDirectMemorySize=64M -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005</jvmArguments>
</configuration>
</plugin>
But direct memory is still setup to 10M :(
which I can see in log file when the app is booting up:
Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -agentpath:/layers/paketo-buildpacks_bellsoft-liberica/jvmkill/jvmkill-1.16.0-RELEASE.so=printHeapHistogram=1 -XX:ActiveProcessorCount=8 -XX:MaxDirectMemorySize=10M -Xmx11521920K -XX:MaxMetaspaceSize=144375K -XX:ReservedCodeCacheSize=240M -Xss1M -Dorg.springframework.cloud.bindings.boot.enable=true
Can anybody advise me what Am I doing wrong?
NOTES:
Spring Boot: 2.3.7.RELEASE
when I run docker image manually with -e, change of jvm argument is working:
docker run -e JAVA_TOOL_OPTIONS=-XX:MaxDirectMemorySize=64M docker.io/example/app-name:0.0.1
this mvn plugin is using Buildpack to create the docker image:
https://paketo.io/docs/buildpacks/language-family-buildpacks/java/#about-the-jvm
UPDATE:
by the doc this should be working solution but it is not:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
<image>
<name>docker.io/example/${project.artifactId}:${project.version}</name>
<env>
<JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=64M</JAVA_TOOL_OPTIONS>
</env>
</image>
</configuration>
this is a working solution on how to make runtime env "sticky":
....
<image>
<name>docker.io/example/${project.artifactId}:${project.version}</name>
<env>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=64M</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
</env>
</image>
...
spring-boot-maven-plugin is using paketo buildpacks:
doc:
https://github.com/paketo-buildpacks/environment-variables
It depends on your goal here. It sounds like you want to change the max direct memory in your container when your app runs so you should be just doing what you indicated works here (and what's listed in the docs).
docker run -e JAVA_TOOL_OPTIONS=-XX:MaxDirectMemorySize=64M docker.io/example/app-name:0.0.1
The doc link you're referencing is talking about configuring options at runtime which is what you are doing with the env variables.
For anyone using Docker on Mac + Spring Boot's build-image, be aware that as of writing the default setting of Docker on Mac is a 2GB VM image that runs Linux with Docker running inside this linux VM.
With the current Spring 2.3.X default Pareto builder, this results in a docker image that has ~300MB available, but a fairly simple spring app (for me) needs ~600MB according to the memory calculator.
So no matter what the value of maxDirectMemorySize, it just would not work. As soon as I upped the mem available to the docker VM it worked just fine
This post on javapapers.com shows how to run a JMH benchmark in Maven by typing mvn exec:exec. Running JMH within Maven is pretty handy, since you can easily run it from an Eclipse Run Configuration or even in a Maven phase.
However, there are two problems with this setup:
When you kill Maven, JMH will continue running in the background, as exec:exec starts it in a separate VM.
Usually, JMH will start yet another VM to run the benchmarks, so you will end up with at least 3 VMs running at the same time.
Fortunately, the Exec Maven Plugin comes with a second goal, exec:java, which executes a main class directly in the VM Maven runs. However, when I tried to configure Maven to run JMH using exec:java, the benchmark crashes because of missing classes:
# JMH 1.11.3 (released 40 days ago)
# VM version: Error: Could not find or load main class org.openjdk.jmh.runner.VersionMain
# VM invoker: C:\Program Files\Java\jdk1.7.0\jre\bin\java.exe
[...]
# Run progress: 0.00% complete, ETA 00:02:40
# Fork: 1 of 1
Error: Could not find or load main class org.openjdk.jmh.runner.ForkedMain
<forked VM failed with exit code 1>
Here is the relevant part of the pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>my.Benchmark</mainClass>
</configuration>
</plugin>
And here is how I run JMH from my.Benchmark:
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder().include(my.Benchmark.class.getSimpleName())
.forks(1).build();
new Runner(options).run();
}
I realize that JMH uses the java.class.path system property to determine the classpath for the forked VMs and that this property does not contain Maven's project dependencies. But what is the preferred way to deal with this?
While my previous answer requires modifying the benchmark program, here is a POM-only solution that sets the java.class.path system property to the runtime classpath with the help of the Dependency Plugin:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>build-classpath</id>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputProperty>depClasspath</outputProperty>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>my.Benchmark</mainClass>
<systemProperties>
<systemProperty>
<key>java.class.path</key>
<value>${project.build.outputDirectory}${path.separator}${depClasspath}</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
One way to work around this problem is to extract the "effective" classpath from the class loader of the my.Benchmark class before calling JMH from my main method:
URLClassLoader classLoader = (URLClassLoader) my.Benchmark.class.getClassLoader();
StringBuilder classpath = new StringBuilder();
for(URL url : classLoader.getURLs())
classpath.append(url.getPath()).append(File.pathSeparator);
System.setProperty("java.class.path", classpath.toString());
This seems to work, but it feels a lot like a hack that shouldn't be necessary...
I am trying to create an RPM package to install a piece of software however whenever I try to build it using the rpm plugin it will run the install script while building which will fail since my machine is not the intended target (nor should it be)
The setup is this
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.1.2</version>
<extensions>true</extensions>
<configuration>
<group>Applications/Software</group>
<mappings>
<mapping>
<directory>/tmp/${project.artifactId}</directory>
<filemode>755</filemode>
<username>user</username>
<groupname>group</groupname>
<sources>
<source>
<location>src/main/resources/</location>
</source>
</sources>
</mapping>
</mappings>
<requires>
<require>unzip</require>
</requires>
<preinstallScriptlet>
<scriptFile>src/main/scripts/preinstall.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</preinstallScriptlet>
<installScriptlet>
<scriptFile>src/main/scripts/install.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</installScriptlet>
</configuration>
</plugin>
I have also configured the pom packaging to be rpm and I am running "mvn clean package" to generate the rpm.
This is just a builder project meaning that all it is meant to do is to package all files within src/main/resources in the rpm together with scriptlets which will execute when that rpm is run on some target machine.
Am I missing something?
I am building the rpm on an Ubuntu 14.04 machine with rpmbuild installed
I just read the RPM documentation and found out that this is totally correct. The install scriptlet is called when the RPM is build, what you probably need is a preinstall or postinstall scriptlet. The installation itself (copying the files) is done by RPM.
Reference: http://www.rpm.org/max-rpm/s1-rpm-inside-scripts.html
I'm getting PermGen out of memory error on every build at travis-ci. This is my configuration file:
language: java
env:
global:
- MAVEN_OPTS="-XX:MaxPermSize=512m -Xmx4g"
script: mvn clean install
Looks like MAVEN_OPTS is not working, since the same values on another server make the build successful.
Here is one of the builds: https://travis-ci.org/tpc2/requs/builds/23383360
Your build link is no longer valid, so I'm going to make a guess. Are you getting the PermGen during surefire tests? That plugin uses a separately configured arg line. Our builds are configured like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<configuration>
<argLine>${argLine} -Xmx512m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
You can set JVM memory settings in MAVEN_OPTS by adding this to .travis.yml:
before_install: echo "MAVEN_OPTS='-Xmx2048m -XX:MaxPermSize=512m'" > ~/.mavenrc
I'm using the maven jetty plugin to run my two web applications. One web application is spring mvc UI and the other is a RESTful web application. I able to get the two web applications to communicate when I run two separate mvn jetty:run instances and assign different ports. I have successfully deploy both in the same jetty instance using the same port using the below maven pom.xml configuration. I eventually get a ava.lang.OutOfMemoryError: PermGen space error. What is the best workaround for this?
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.6.8.v20121106</version>
<configuration>
<jvmArgs>-Xmx2024m -Xms2024m</jvmArgs>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>../../api/target/main-api.war</war>
<contextPath>/test</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
</plugin>
Add following jvm argument, if you get error regarding cannot allocate memory then try using lesser value (128 and 256)
-XX:PermSize=256M -XX:MaxPermSize=512M
Reference
What is 'PermSize' in Java?
-XX:MaxPermSize with or without -XX:PermSize
Try running Jetty in forked mode like this:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.6.8.v20121106</version>
<executions>
<execution>
<id>start-jetty</id>
<!-- Set this to the appropriate phase:
pre-integration-test, or earlier test-compile-->
<phase>pre-integration-test</phase>
<goals>
<goal>run-forked</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArgs>-Xmx2048m -Xms1536m -XX:PermSize=128m -XX:MaxPermSize=256m</jvmArgs>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>../../api/target/main-api.war</war>
<contextPath>/test</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
</plugin>
For more details check Running Jetty in a forked JVM.
And... Make sure you really have 2048 MB of free RAM before starting this.
Try using Plumbr to diagnose any memory leak issues with both your web apps.
http://plumbr.eu/
I eventually get a java.lang.OutOfMemoryError: PermGen space error
How long is eventually? Is one of the webapps redeploying frequently due to changes?
It is very easy to leak classes when redeploying a web app. I would run maven with this setting added to MAVEN_OPTS
-XX:+HeapDumpOnOutOfMemoryError
Run until you get an out of memory error, then load the dump with eclipse mat and see what is filling up your perm gen. Most likely your web app is leaking classes on redeploy.
It depends on which JVM instance require more memory. As example, if tests are forked (by default), and fails due OutOfMemoryError then try configure plugin which launching them:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>
OR
Apart from heap memory. You have to increase perm size also to resolve that exception in maven use these variables in environment variable. And Sometimes is good also to extend perm memory size -
Set the environment variable:
variable name: MAVEN_OPTS variable value: -Xmx512m -XX:MaxPermSize=256m
Compiled data from resource
Please clarify: what jvm version you are using, what operating system you are on, how many physical memory is installed on your computer. What happen if you reduce your memory requirements for example to 1400M (it could help if you run on 32bit jvm), i.e.:
<jvmArgs>-Xmx1400m -Xms1400m</jvmArgs>