Как указать аргумент JVM для Maven built executable JAR
при использовании Maven для создания исполняемого JAR, как указать аргументы JVM, которые используются при выполнении JAR?
Я могу указать основной класс, используя <mainClass>
. Я подозреваю, что есть аналогичный атрибут для Аргументов JVM. Специально мне нужно указать максимальную память (пример-Xmx500m).
вот мой плагин сборки:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.me.myApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Edit/Follow-up: кажется, что невозможно указать аргументы JVM для исполняемого JAR согласно этой и этой пост.
5 ответов
Я не знаю такого механизма. Конфигурация JVM задается вызывающей командой java.
вот спецификация файла jar, которая явно не упоминает какой-либо атрибут, кроме основного класса для автономного выполнения:
http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html
во-первых, позвольте мне сказать, что все это сложно, это наверное сложно для разума.
этот подход может работать для вас, если вам это действительно нужно. Как написано, предполагается, что "java" находится на пути вызывающего абонента.
описание:
объявите класс загрузчика в качестве основного класса в манифесте jar.
загрузчик порождает другой процесс, в котором мы вызываем java (передавая любые аргументы командной строки вам хочу) на "реальном" основном классе.
перенаправить систему дочерних процессов.и системы.err для соответствующих потоков загрузчика
дождитесь завершения дочернего процесса
здесь хорошая справочная статья.
src / main / java / scratch / Bootstrap.java - этот класс определен в pom.xml как
mainclass кувшина : <mainClass>scratch.Bootstrap</mainClass>
package scratch;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
public class Bootstrap {
class StreamProxy extends Thread {
final InputStream is;
final PrintStream os;
StreamProxy(InputStream is, PrintStream os) {
this.is = is;
this.os = os;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
os.println(line);
}
} catch (IOException ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
}
private void go(){
try {
/*
* Spin up a separate java process calling a non-default Main class in your Jar.
*/
Process process = Runtime.getRuntime().exec("java -cp scratch-1.0-SNAPSHOT-jar-with-dependencies.jar -Xmx500m scratch.App");
/*
* Proxy the System.out and System.err from the spawned process back to the user's window. This
* is important or the spawned process could block.
*/
StreamProxy errorStreamProxy = new StreamProxy(process.getErrorStream(), System.err);
StreamProxy outStreamProxy = new StreamProxy(process.getInputStream(), System.out);
errorStreamProxy.start();
outStreamProxy.start();
System.out.println("Exit:" + process.waitFor());
} catch (Exception ex) {
System.out.println("There was a problem execting the program. Details:");
ex.printStackTrace(System.err);
if(null != process){
try{
process.destroy();
} catch (Exception e){
System.err.println("Error destroying process: "+e.getMessage());
}
}
}
}
public static void main(String[] args) {
new Bootstrap().go();
}
}
src / main / java / scratch / App.java - это обычная точка входа для вашей программы
package scratch;
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World! maxMemory:"+Runtime.getRuntime().maxMemory() );
}
}
тел.: java -jar scratch-1.0-SNAPSHOT-jar-with-dependencies.jar
Возвращает:
Hello World! maxMemory:520290304
Exit:0
в ответ на ответ Дэвида Карлсона вы можете сделать его менее хрупким, используя java.свойство home system для поиска исполняемого файла java вместо того, чтобы полагаться на путь пользователя, чтобы найти его. Кроме того, вы, вероятно, должны перенаправлять стандартный ввод в дочерний процесс.
Я думаю, что это можно сделать, если вы думаете об этом таким образом.
Создать .bat
файл, который будет иметь команду:
> java .. yourClass.. -D<jvmOption1> -D<jvmOption2>...
вы можете попробовать посмотреть на это плагин ассемблера приложений для maven.
я попробовал и, кажется, работает. Я до сих пор не знаю, как это сделать .файл bat должен быть сгенерирован с несколько другим контентом, но я думаю, что это выполнимо.
в качестве другого варианта вы всегда можете попытаться создать .bat файл в подпапка ресурсов вашего проекта и включите эту подпапку в свой дистрибутив.
древний вопрос, но пришел на мой поиск Google для этой точной проблемы, поэтому я отвечаю на него.
попробовать
<configuation>
...
<argLine> -Xmx500m </argLine>
...
</configuation>