Меня давно занимала мысль как в 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 пакет и выложить всё на гитхабе.

У меня проблема с файлами.jar, дважды щелкнув их. Когда я перехожу к диалогу свойств, я не могу найти Java-only Archive Manager в списке программ. Но -jar somefile.jar открывает программу.

Related of "Как запустить файл.jar с помощью двойного щелчка?"

Возможно, у вас нет установленной среды выполнения!

Чтобы установить его, попробуйте выполнить следующие инструкции.

Sudo apt-get install openjdk-7-jre

Или вы можете установить Oracle JRE с использованием метода PPA со следующими командами.

Sudo add-apt-repository ppa:ferramroberto/java sudo apt-get update sudo apt-get install sun-java6-jre sun-java6-plugin sun-java6-fonts

Затем, чтобы использовать его для открытия файлов.jar, попробуйте следующее.

  1. Щелкните правой кнопкой мыши файл.jar> Свойства.
  2. Нажмите на вкладку «Открыть с» вверху.
  3. Измените выбор по умолчанию как Sun Java 6 Runtime.
  4. Нажмите «Закрыть», и вы должны быть готовы к двойному щелчку.

Чтобы сделать Java открытым.jar-файлы по умолчанию (т.е. дважды щелкните), щелкните правой кнопкой мыши на любом файле.jar, чтобы выбрать « Свойства» . В следующем окне выберите вкладку «Открыть с», чтобы увидеть, например, следующий выбор:

Выберите время выполнения Java и нажмите Установить по умолчанию, чтобы это приложение по умолчанию открывало файлы.jar.

Добавление файла с именем /usr/share/applications/java.desktop со следующим содержимым должно сделать трюк.

Name=Java Comment=Java GenericName=Java Keywords=java Exec=java -jar %f Terminal=false X-MultipleArgs=false Type=Application MimeType=application/x-java-archive StartupNotify=true

После добавления этого файла вы сможете найти запись под названием Java в Open file with...-Dialog

ЗАЯВКА НА ЗАЯВКУ

После установки среды выполнения Java вы можете создать значок запуска, как и другие приложения в системе, создав файл *.desktop .
Это делает вещи проще и красивее!

    Создайте папку в каталоге по вашему выбору с файлами *.jar (приложение) и *.png (значок приложения). В этом случае я буду использовать каталог /usr/share/folder . Для ~/folder это хорошая идея назвать ее именем приложения, например, если приложение VUE называет папку ~/VUE или ~/vue .

    Откройте терминал и запустите следующую строку кода:

    Sudo mkdir /usr/share/folder

    Или откройте диспетчер файлов (в этом случае Nautilus) с привилегиями супер администратора, запустив следующую строку кода в терминале:

    Gksu nautilus

    После этого перейдите в /usr/share и создайте folder с графическим интерфейсом.

    Также в терминале и выполните следующую строку кода:

    Gksu gedit /usr/share/applications/*.desktop

    (Вы могли бы использовать ваш редактор по выбору. В этом случае использовался Gedit .)

    Вставьте следующие строки кода в редактируемый файл:

    Encoding=UTF-8 Name=Name Categories=Category Name Exec=java -jar /usr/share/folder/*.jar Icon=/usr/share/folder/*.png StartupNotify=false Terminal=false Type=Application Comment=Application Name StartupWMClass=Class MimeType=application/*

    Сохраните файл. (* Всегда одно и то же имя.)

ИСПОЛНЕНИЕ ПРИЛОЖЕНИЯ

Для размеров значков Linux поддерживает различные форматы изображений (PNG, JPG, SVG и т. Д.) И размеры (16×16 ~ 512×512 px). Вы можете использовать файл PNG размером 32×32 ~ 96×96 пикселей или файл SVG размером 128×128 ~ 512×512 пикселей для получения лучших результатов. В этом случае я думаю, что PNG размером 96×96 пикселей достаточно для красивого рабочего стола / Dash.

Для получения дополнительной информации посмотрите:

  • Спросите Ubuntu – Почему некоторые иконы имеют столько разных размеров?
  • Разработчик Gnome – виды иконок

АССОЦИАЦИЯ ФАЙЛОВ

Для этого шага вам нужно создать MIME Tipe , если он не существует, и связать его с приложением в файле mimeapps.list . Для этого взгляните на следующее:

Примечание. Если вы найдете что-то неправильное, не стесняйтесь редактировать и исправлять. Благодаря!