Я знаю, что вы просили о методах создания, не связанных с проектами, для достижения этой цели, но, поскольку эта конкретная проблема была в моей голове довольно долгое время, я решил, что добавлю другую альтернативу.
TLDR: перейдите к разделу «Создание исполняемой команды CLI» ниже
Справочная информация
У меня был почти такой же список требований, как вы делали некоторое время назад и приземлилсяна создание исполняемых файлов JAR.Я не говорю об исполняемых файлах через java -jar myfile.jar
, а скорее о автономных uber-jar-файлах, которые вы можете запускать напрямую, как и при работе с любым другим двоичным файлом.
Если вы прочитали спецификацию zip-файла (к которой относятся jar-файлы, поскольку jar-файл является zip-файлом), оказывается, что это действительно возможно.Короткая версия заключается в том, что вам необходимо:
- собрать толстый jar с необходимым вам материалом
- вставить скрипт bash / bat / shell в двоичный контент jar в началеваш файл
chmod +x
файл Uber JAR (или, если в Windows, установите флажок исполняемого файла) - переписать записи метаданных JAR-файла, чтобы вставленный текст скрипта не лишал законной силы почтовый индексвнутренние смещения файла
Следует отметить, что это фактически поддерживается спецификацией zip-файла.Вот как работают самораспаковывающиеся zip-файлы и т. Д., И получившийся толстый jar (после описанного выше процесса) по-прежнему является действительным jar-файлом и действительным zip-архивом.Все соответствующие команды, такие как java -jar
, все еще работают, и файл теперь также исполняется непосредственно из командной строки.
Кроме того, следуя вышеприведенному шаблону, также можно добавить поддержку таких вещей, как drip jvm launcher , что значительно ускоряет время запуска ваших сценариев cli.
Как оказалось, когда я начал изучать это около года назад, библиотеки для последней точки перезаписи метаданных jar-файла не существовало.Не только в ближайшем будущем, но и на JVM в целом.Это все еще поражает воображение: центральная единица развертывания всех языков в jvm - это файл jar, и не было никакой библиотеки, которая фактически читала бы внутренние файлы jar.Внутренние компоненты, как в реальной структуре zip-файлов, а не только то, что делает ZipFile и друзья java.
Кроме того, я не смог найти библиотеку для clojure, которая имела бы дело с видом бинарной структуры, требуемой спецификацией zip-файла дляпуть.
Решение:
- октет имеет то, что я считаю наиболее чистым интерфейсом из доступных двоичных библиотек для clojure, поэтому я написал запрос на извлечение октета , добавив поддержкуфункции, требуемые спецификацией zip-файла.
- Затем я создал новую библиотеку clj-zip-meta , которая считывает и интерпретирует метаданные файла zip и может перезаписывать смещение, как описано в последнем пункте выше.
- Затем я создал запрос на получение для существующей библиотеки clojure lein-binplus , чтобы добавить поддержку перезаписи zip-мета, реализованной с помощью clj-zip-meta, а также добавитьподдержка пользовательских сценариев преамбулы, позволяющих создавать реальные исполняемые файлы jar без необходимости
java -jar
. - После всего этого я создал шаблон leiningen cli-cmd для поддержки создания командных проектов cli, которые поддерживают все перечисленные выше функции и имеют хорошо структурированную настройку синтаксического анализа командной строки ... илито, что я считал хорошо структурированным:).Комментарии приветствуются.
Создание исполняемой команды CLI
Итак, вы можете создать новое приложение clojure для командной строки с leiningen и запустить его, используя:
~> lein new cli-cmd mycmd
~> cd mycmd
~> lein bin
Compiling mycmd.core
Compiling mycmd.core
Created /home/mbjarland/tmp/clj-cmd/mycmd/target/mycmd-0.1.0-SNAPSHOT.jar
Created /home/mbjarland/tmp/clj-cmd/mycmd/target/mycmd-0.1.0-SNAPSHOT-standalone.jar
Creating standalone executable: /home/mbjarland/tmp/clj-cmd/mycmd/target/mycmd
Re-aligning zip offsets
~> target/mycmd
---- debug output, remove for production code ----
options {:port 80, :hostname "localhost", :verbosity 0}
arguments []
errors nil
summary
-p, --port PORT 80 Port number
-H, --hostname HOST localhost Remote host
--detach Detach from controlling process
-v Verbosity level; may be specified multiple times to increase value
-h, --help
--------------------------------------------------
This is my program. There are many like it, but this one is mine.
Usage: mycmd [options] action
Options:
-p, --port PORT 80 Port number
-H, --hostname HOST localhost Remote host
--detach Detach from controlling process
-v Verbosity level; may be specified multiple times to increase value
-h, --help
Actions:
start Start a new server
stop Stop an existing server
status Print a server's status
Please refer to the manual page for more information.
Error: invalid action '' specified!
Там, где выходные данные команды - это просто пример синтаксического анализа командной строки, который я добавил в шаблон leiningen.
Настраиваемый сценарий преамбулы находится по адресу boot/jar-preamble.sh
и имеет поддержку функции drip.Другими словами, если у вас есть путь к файлу, сгенерированный исполняемый файл будет использовать его, в противном случае он вернется к стандартному java -jar
способу запуска uber jar для внутреннего использования.
Исходный код для разбора командной строки и код для приложения cli находятся в каталоге src, как обычно.
Если вам захочется взломать, можно изменить сценарий преамбулы и повторно запустить lein bin
, и новая преамбула будет вставлена в ваш исполняемый файл в процессе сборки.
Также следует отметить, что этот метод все еще делает java -jar
под одеялом, поэтому вам нужно нужна Java на вашем пути.
Ayway, многословное объяснение,но, надеюсь, это будет полезно для кого-то с этой проблемой.