Как указать аргумент JVM для встроенного исполняемого файла JAR Maven - PullRequest
7 голосов
/ 11 октября 2008

При использовании 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>

Редактирование / продолжение: Возможно, невозможно указать аргументы JVM для исполняемого JAR в соответствии с this и this post.

Ответы [ 5 ]

4 голосов
/ 12 октября 2008

Я не знаю ни одного такого механизма. Конфигурация JVM определяется вызывающей командой java.

Вот спецификация файла jar, которая явно не упоминает никаких атрибутов, кроме Main-Class для автономного выполнения:

http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html

2 голосов
/ 12 октября 2008

Во-первых, позвольте мне сказать, что все это сложно, вероятно, по какой-то причине.

Этот подход может работать для вас, если он вам действительно нужен. Как написано, предполагается, что "java" находится на пути звонящего.

Обзор:

  1. Объявите класс Bootstrapper в качестве основного класса в манифесте фляги.

  2. Загрузчик запускает другой процесс, в котором мы вызываем java (передавая любые аргументы командной строки, которые вы хотите) в «реальном» главном классе.

  3. Перенаправить дочерние процессы System.out и System.err в соответствующие потоки загрузчика

  4. Дождаться завершения дочернего процесса

Вот хорошая справочная статья .

src / main / java / scratch / Bootstrap.java - этот класс определен в pom.xml как Основной класс банки: <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
0 голосов
/ 17 апреля 2018

Я думаю, что это можно сделать, если подумать об этом. Создайте файл .bat, который будет иметь команду:

> java .. yourClass.. -D<jvmOption1> -D<jvmOption2>...

Вы можете попробовать этот плагин для ассемблера приложений для maven.

Я попробовал, и, кажется, работает. Я до сих пор не понимаю, как сделать файл .bat с несколько иным содержанием, но думаю, что это выполнимо.

В качестве другого варианта вы всегда можете попытаться создать файл .bat в подпапке ресурсов вашего проекта и включить эту подпапку в свой дистрибутив.

0 голосов
/ 05 июня 2013

В ответ на ответ Дэвида Карлсона вы можете сделать его менее хрупким, используя системное свойство java.home, чтобы найти исполняемый файл java, а не полагаться на путь пользователя, чтобы найти его. Кроме того, вам, вероятно, следует перенаправить стандартный ввод и на дочерний процесс.

0 голосов
/ 21 октября 2011

Древний вопрос, но я нашел в поиске Google именно эту проблему, поэтому я отвечаю на него.

Попробуйте

<configuation>
...
<argLine> -Xmx500m </argLine>
...
</configuation>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...