Открыть банку из другой банки - PullRequest
0 голосов
/ 27 октября 2010

Та же старая проблема ... Я хочу запустить свой jar на Mac или Linux с большим выделением памяти. Я не хочу, чтобы пользователь открывал Терминал и писал java -XMx512 -jar MainJar.jar вручную.

Я видел множество решений, чтобы это исправить ... Но мне было интересно, может ли это сработать: " Выполнение команды терминала java -XMx512 -jar MainJar.jar в Jar ( B) инициализировать Jar (A) с выделением 512 МБ памяти.".

В Jar (B) я пробовал этот код для запуска Jar (A), и он работал нормально:

public static void main(String[] args) throws Exception{
   String jarName = "MainJar.jar";  // Jar(A) name.
   Desktop.getDesktop().open( new File( jarName ) );
}

Но все же я не выделил память для Jar (A) при инициализации из Jar (B), поэтому я могу написать код в Jar (B) для запуска Терминала и дать ему команду для его выполнения: " java -XMx512 -jar MainJar.jar "?

------------------------------ Отредактировано в соответствии с просьбой сделать его более понятным.

1 Ответ

2 голосов
/ 27 октября 2010

Вы можете использовать Runtime.exec() или ProcessBuilder для этого.

Process proc = new ProcessBuilder("java", "-XMx512M", "-jar", "MainJar.jar").start();
int result = proc.waitFor();

Но, честно говоря, я думаю, что это ужасное решение.Я бы предпочел инсталляционный пакет типа InstallAnywhere.В противном случае я бы использовал скрипт оболочки для запуска Jar.Инкапсуляция его в банку, где его нельзя редактировать, раздражает пользователей, и теперь у вас есть параллельные зависимости, а не один файл.

Если вы собираетесь пойти по этому маршруту, можно было бы использоватьта же банка для обеих целей.Добавьте файл класса для запуска с правильными параметрами в Jar, скажем AppLauncher.class.Мы предполагаем, что реальный код вашей программы начинается с Main.class.

public class AppLauncher {
     public static void main(String... args) {
        Process proc = new ProcessBuilder("java", "-XMx512M", "-cp", "MyJar.jar", "Main").start();
        int result = proc.waitFor();
     }
}

Тогда у вас будет файл манифеста точки jar для этого основного класса :

 Main-Class: AppLauncher

Затем вы выполните эту банку через

java -jar MyJar.jar

Или через сопоставление файлов (двойной щелчок).

При запуске он выполняет команду java -Xmx512M -cp MyJar.jar Main, которая запускает метод main класса Main вашего jar-файла.В обоих вызовах используется один и тот же jar: первый раз, когда он автоматически запускает AppLauncher.main() через файл манифеста, второй раз Main.main() через явный вызов процесса.

Конечно, это все еще хрупко.Во-первых, предполагается, что в качестве рабочего каталога установлена ​​папка, в которой находится файл JAR.Это не всегда так.

Редактировать : На всякий случай, если вы не уверены, что поступите иначе, и действительно выберете маршрут ProcessBuilder, здесь есть нечто большее, чем просто то, что я заметил. Есть ловушки, которых следует избегать .Например, я не читал из выходного потока процесса (используя Process.getInputStream()), поэтому, если дочерний процесс Java выводит что-либо в стандартный вывод, он будет зависать при заполнении буфера ОС.

...