Как открыть jar файл на linux. Запуск Java классов и JAR-ов не по учебнику

20.04.2019

20 ответов

Самый простой маршрут - это, вероятно, обновление или повторная установка Java Runtime Environment (JRE).

Если вам нужно распространять ваш.jar файл и сделать его доступным для других компьютеров Windows, вы можете сделать простой.bat файл, как это, в командной строке:

Java -jar MyJavaTool.jar

и поместите файл.bat в тот же каталог, что и ваш.jar файл.

Интересным побочным эффектом этого является проблема при запуске исполняемых файлов jar в командной строке.

Если вы попробуете (в командной строке)

jarfile.jar параметр

Нет радости, потому что это переводится на следующее (это не работает):

javaw.exe -jar jarfile.jar параметр

однако работает следующая команда:

java.exe -jar jarfile.jar параметр

Если вы изменили связь в диспетчере файлов, как описано выше, выполните следующие действия:

"C:\Program Files\Java\j2re1.4.2_04\bin\java.exe" -jar "% 1" % *

вы можете ввести:

jarfile.jar параметр

в командной строке, и теперь он будет работать! EDIT: (Тем не менее, вы получаете черное окно консоли при запуске Java-приложения на основе формы (не консольное), поэтому это не идеальное решение)

Если вы запустите эти файлы jar, дважды щелкнув их в окнах, параметры не будут переданы, поэтому ваш Java-код должен обрабатывать исключение и включать функцию "нажать клавишу" в конце или окно просто исчезнет.

Чтобы передать параметр в окнах, вы должны создать ярлык для файла jar, который включает в себя параметр в целевой строке (щелкните правой кнопкой мыши по ярлыку и выберите свойства), вы не можете добавить параметры в значок файла jar таким образом.

Здесь нет единого, согласованного решения, но у вас будет такая же проблема с любым другим консольным приложением.

Существует бесплатное приложение Windows, называемое "bat to exe", которое вы можете использовать для создания exe файла из.bat файла с соответствующей командной строкой в ​​нем. вы также можете вставить файл jar в exe с этим приложением и очистить его, когда он закончит работать, поэтому это может быть более элегантное решение.

В Windows XP * вам нужно всего две команды оболочки:

C:\>ftype myjarfile="C:\JRE1.6\bin\javaw.exe" -jar "%1" %* C:\>assoc .jar=myjarfile

очевидно, используя правильный путь для JRE и любое имя, которое вы хотите вместо myjarfile .

Чтобы просто проверить текущие настройки:

C:\>assoc .jar C:\>ftype jarfile

на этот раз, используя значение, возвращаемое первой командой, если она есть, вместо jarfile .

* не протестирован с Windows 7

Существует способ, не требующий от пользователя изменений на своем ПК. Runtime.getRuntime.exec() позволяет нам запускать cmd.exe и выполнять команды внутри него. Таким образом, возможно, что программа java запускается в командной строке, когда пользователь нажимает на.jar файл.

Public static void main(String args) throws IOException { if(args.length == 0) { Process p = Runtime.getRuntime().exec("cmd.exe /c start java -jar " + (new File(NameOfClass.class.getProtectionDomain().getCodeSource().getLocation().getPath())).getAbsolutePath() + " cmd"); } else { //code to be executed } }

Помимо всех других предложений, есть еще одна вещь, которую вам нужно рассмотреть. Ваша консольная программа helloworld.jar? Если это так, то я не верю, что вы сможете превратить его в двойной файл jar. Консольные программы используют регулярное окно оболочки cmd.exe для их ввода и вывода. Обычно jar "launcher" привязан к javaw.exe, который не создает окно командной оболочки.

Вы хотите проверить пару вещей; если это ваш собственный файл jar, убедитесь, что вы определили Main-класс в манифесте. Поскольку мы знаем, что вы можете запустить его из командной строки, нужно сделать так, чтобы создать ярлык Windows и изменить свойства (вам придется осмотреться, у меня нет машины Windows, на которую вы смотрите), так что команда, которую он выполняет при открытии, - это команда java -jar, о которой вы упомянули.

Другое дело: если что-то не смущает, оно должно работать в любом случае; проверьте и убедитесь, что у вас есть java, связанная с расширением.jar.

У меня была такая же проблема в Windows 10. Я исправил ее с помощью righ-click на helloworld.jar "и перейдите в свойства и нажмите кнопку изменить в разделе" Открывает с: "и выберите" Найти другое приложение на этом ПК ". В диалоговом окне" Открыть с... "перейдите в папку вашей папки Java на своем ПК и откройте соответствующую папку jdk, а затем откройте папку bin и выберите" javaw.exe "оттуда. Затем в следующий раз ваш" helloworld.jar " откроется обычным способом.

Пример использования Java: " C:\Program Files (x86)\Java\jdk1.8.0_111\bin ".

Другой способ запуска jar файлов с помощью щелчка/двойного щелчка состоит в том, чтобы добавить "-jar" к имя файла. Например, вы переименовали бы файл MyJar.jar в -jar MyJar.jar .

Вы должны иметь.class файлы, связанные с java.exe , конечно. Это может не работать во всех случаях, но для меня это работало больше всего.

Если вам нужно запустить файл jar, дважды щелкнув по нему, вы должны создать его как " Runnable JAR ". вы можете сделать это просто со своей IDE.

Если вы используете eclipse, выполните следующие действия:

To create a new runnable JAR file in the workbench: 1.From the menu bar File menu, select Export. 2.Expand the Java node and select Runnable JAR file. Click Next. 3.In the Opens the Runnable JAR export wizard Runnable JAR File Specification page, select a "Java Application" launch configuration to use to create a runnable JAR. 4.In the Export destination field, either type or click Browse to select a location for the JAR file. 5.Select an appropriate library handling strategy. Optionally, you can also create an ANT script to quickly regenerate a previously created runnable JAR file.

дополнительную информацию можно найти на странице справки Eclipse:

Меня давно занимала мысль как в Linux-е запускать программы на Java без вспомогательных Bash скриптов. Я не видел приемлемого решения, если не считать способ «bash script payload», когда в конец скрипта помещается бинарный файл.

Но на прошлой неделе случайно наткнулся на модуль ядра binfmt_misc, с помощью которого можно перехватить исполнение файла по его magic number. Для этого через update-binfmts добавляется собственный обработчик для получения имени исполняемого файла и аргументов пользователя.

Первое открытие

Как оказалось в моей Ubuntu 16.04 уже зарегистрирован обработчик для JAR файлов:

Update-binfmts --display ... jar (enabled): package = openjdk-8 type = magic offset = 0 magic = PK\x03\x04 mask = interpreter = /usr/bin/jexec detector =
Отдав команду chmod +x foo.bar я радостно потирал руки, но реальность оказалось сурова - запуск ./foo.jar выдал следующее:

Invalid file (bad magic number): Exec format error
Погуглив, я нашел обросший мхом баг bugs.java.com/bugdatabase/view_bug.do?bug_id=6401361 Как оказывается сборка через Maven не добавляет «0xcafe» в начало JAR файла. Не менее безответственно ведет себя и плагин maven-assembly-plugin. Что не нравится /usr/bin/jexec, зарегистрированному обработчику по умолчанию.

Погуглив еще, я нашел решение проблемы через установку пакета jarwrapper. После установки добавляется новый обработчик /usr/bin/jarwrapper и страховка /usr/bin/jardetector (проверяет по META-INF что это действительно JAR). Но изучив код обработчика мне не понравилась куча лишней работы, которую делает скрипт запуская множество вспомогательных программ.

Поэтому решением стал собственный обработчик:

#!/bin/sh #/usr/bin/jarinvoke JAR=$1 shift exec java -jar $JAR $@
Дальше открываем файл sudo gedit /var/lib/binfmts/jar и регистрируем обработчик заменив строчку с /usr/bin/jexec на /usr/bin/jarinvoke. На самом деле это плохое решение и лучше создать собственную группу (об этом ниже), но для первичного понимания сойдет.

Для вступления изменений в силу может потребоваться выполнить:

Sudo update-binfmts --disable jar && sudo update-binfmts --enable jar
После чего можете запускать JAR файлы как любые другие исполняемые файлы.

Исполняемые классы

Теперь можно идти дальше и сделать из Java классов исполняемые файлы, где jarwrapper не сможет помочь. Обработчик будет работать только для классов с пакетом по умолчанию (т.е. классы с отсутствующим package заголовком). Может можно сделать и лучше, но мне хватило такой функциональности для «скриптования» на Java:

#!/bin/sh # /usr/bin/clsinvoke CLASS_FILE=$1 shift ABSOLUTE_PATH=`readlink -f $CLASS_FILE` CLASS=`basename $ABSOLUTE_PATH` CLASS=${CLASS%.*} CLASSPATH=`dirname $ABSOLUTE_PATH` exec java -cp $CLASSPATH $CLASS $@
После чего регистрируем собственный обработчик (этим же способом можно создать новый обработчик для JAR-ов не редактируя /usr/bin/jexec):

Sudo update-binfmts --package clsinvoke --install clsinvoke /usr/bin/clsinvoke --magic "\xca\xfe\xba\xbe"
Тестируем:

Public class HelloWorld { public static void main(String args) { System.out.println("Hello, World"); } }
javac HellWorld.java chmod +x HelloWorld.class ./HelloWorld.class Hello, World
Можно пойти и дальше, сделав более сложный обработчик, который по импорту классов будет определять какие библиотеки добавить в CLASSPATH из ~/.m2, но это отдельная история. Сейчас интересен взгляд со стороны, замечания, дополнения, если таковые есть. После чего думаю оформить это в deb пакет и выложить всё на гитхабе.

Меня давно занимала мысль как в Linux-е запускать программы на Java без вспомогательных Bash скриптов. Я не видел приемлемого решения, если не считать способ «bash script payload», когда в конец скрипта помещается бинарный файл.

Но на прошлой неделе случайно наткнулся на модуль ядра binfmt_misc, с помощью которого можно перехватить исполнение файла по его magic number. Для этого через update-binfmts добавляется собственный обработчик для получения имени исполняемого файла и аргументов пользователя.

Первое открытие

Как оказалось в моей Ubuntu 16.04 уже зарегистрирован обработчик для JAR файлов:

Update-binfmts --display ... jar (enabled): package = openjdk-8 type = magic offset = 0 magic = PK\x03\x04 mask = interpreter = /usr/bin/jexec detector =
Отдав команду chmod +x foo.bar я радостно потирал руки, но реальность оказалось сурова - запуск ./foo.jar выдал следующее:

Invalid file (bad magic number): Exec format error
Погуглив, я нашел обросший мхом баг bugs.java.com/bugdatabase/view_bug.do?bug_id=6401361 Как оказывается сборка через Maven не добавляет «0xcafe» в начало JAR файла. Не менее безответственно ведет себя и плагин maven-assembly-plugin. Что не нравится /usr/bin/jexec, зарегистрированному обработчику по умолчанию.

Погуглив еще, я нашел решение проблемы через установку пакета jarwrapper. После установки добавляется новый обработчик /usr/bin/jarwrapper и страховка /usr/bin/jardetector (проверяет по META-INF что это действительно JAR). Но изучив код обработчика мне не понравилась куча лишней работы, которую делает скрипт запуская множество вспомогательных программ.

Поэтому решением стал собственный обработчик:

#!/bin/sh #/usr/bin/jarinvoke JAR=$1 shift exec java -jar $JAR $@
Дальше открываем файл sudo gedit /var/lib/binfmts/jar и регистрируем обработчик заменив строчку с /usr/bin/jexec на /usr/bin/jarinvoke. На самом деле это плохое решение и лучше создать собственную группу (об этом ниже), но для первичного понимания сойдет.

Для вступления изменений в силу может потребоваться выполнить:

Sudo update-binfmts --disable jar && sudo update-binfmts --enable jar
После чего можете запускать JAR файлы как любые другие исполняемые файлы.

Исполняемые классы

Теперь можно идти дальше и сделать из Java классов исполняемые файлы, где jarwrapper не сможет помочь. Обработчик будет работать только для классов с пакетом по умолчанию (т.е. классы с отсутствующим package заголовком). Может можно сделать и лучше, но мне хватило такой функциональности для «скриптования» на Java:

#!/bin/sh # /usr/bin/clsinvoke CLASS_FILE=$1 shift ABSOLUTE_PATH=`readlink -f $CLASS_FILE` CLASS=`basename $ABSOLUTE_PATH` CLASS=${CLASS%.*} CLASSPATH=`dirname $ABSOLUTE_PATH` exec java -cp $CLASSPATH $CLASS $@
После чего регистрируем собственный обработчик (этим же способом можно создать новый обработчик для JAR-ов не редактируя /usr/bin/jexec):

Sudo update-binfmts --package clsinvoke --install clsinvoke /usr/bin/clsinvoke --magic "\xca\xfe\xba\xbe"
Тестируем:

Public class HelloWorld { public static void main(String args) { System.out.println("Hello, World"); } }
javac HellWorld.java chmod +x HelloWorld.class ./HelloWorld.class Hello, World
Можно пойти и дальше, сделав более сложный обработчик, который по импорту классов будет определять какие библиотеки добавить в CLASSPATH из ~/.m2, но это отдельная история. Сейчас интересен взгляд со стороны, замечания, дополнения, если таковые есть. После чего думаю оформить это в deb пакет и выложить всё на гитхабе.