Как мы с вами ранее уже выясняли, под JVM можно писать вполне себе сносные десктопные приложения. Тут, надо признать, возникают и некоторые тонкости, например, если вам захочется отобразить иконку в трее . К счастью, тонкости проявляются только под Linux. В конце концов, кто же в наше время пользуется на десктопе Linux, пфф… Впрочем, пользователи самой популярной десктопной ОС столкнутся с другой проблемой, а именно необходимостью устанавливать какую-то там ЖэВэЭм. А она непонятно где обитает, весит дофига, а после установки потом еще в трее зависает, обновлений каких-то хочет, мутная штука! Однако пользователей можно заставить страдать чуть меньше обычного, и далее будет показано, как.
Секрет, как вы уже могли догадаться, заключается в том, чтобы встроить JVM в само приложение. Получить такую «встраиваемую» JVM можно несколькими способами. Например, в этой заметке рассказывается, как собрать ее своими силами из JVM с сайта Oracle. А по этой ссылке доступна для скачивания готовая сборка, называется jPortable. Про последнюю вроде как везде очень хорошо отзываются, ею и воспользуемся.
Распаковываем, все каталоги кроме bin и lib вроде как можно смело удалить. Рядом c каталогом bin кладем standalone jar-ник с нашим приложением. Для экспериментов я использовал jar’ник, собранный из проекта к заметке Краткий обзор GUI-фреймворков для Java и мое первое простенькое GUI-приложение на Swing . Рядом кладем run.bat незамысловатого содержания:
binjava.exe -jar swing-look-and-feel-switcher.jar
@echo on
Запускаем и, о чудо, все работает! В реальном проекте вместо bat-файла вы, скорее всего, захотите написать свой небольшой exe-лаунчер с красивой икнокой или создать ярлык на рабочем столе. Ярлык лучше, так как, насколько я помню, некоторые антивирусы и фаерволы обожают показывать страшные сообщения в случаях, когда одна программа (ваш лаунчер) запускает другую (java.exe).
Будучи упакованным в самораспаковывающийся 7-zip архив с максимальной степень сжатия все это хозяйство весит 32 Мб. Многовато, прямо скажем, но и не так, чтобы невероятно много. В наши дни пользователи и не столько качают. В крайнем случае вы можете попытаться выкинуть лишние файлы из каталогов bin и lib, но в этом случае нужно хорошо понимать, что вы делаете. Мне кажется, если вы пишите достаточно серьезное приложение, оно и само по себе будет весить немало. Пользователю нет особой разницы, качать 100 Мб или 132 Мб, особенно, если программа решает действительно актуальную для него задачу. Для сравнения, архив с IntelliJ IDEA 14.1 весит 183 Мб, и всем нормально.
Сборка красивого инстяллятора (разумеется, использующего алгоритм сжатия LZMA, чтобы добиться такой же степени сжатия, как в 7-zip!), к сожалению, выходит за рамки данного поста. В Linux озвученной в заметке проблемы не возникает, так как Java можно указать прямо в зависимостях к deb-пакету. С маками не работаю, так что с вас, дорогие читатели, рассказ в комментариях, как там все устроено.
В рамках поднятой темы нельзя также не отметить существование решений, позволяющих получать из Java-кода нативные приложения, вообще не требующие никакой JVM. В частности, есть такая интересная штука под названием Excelsior JET , но цена у нее довольно кусачая. Специально для разработки под iOS есть решение под названием RoboVM .
А вставала ли перед вами задача встраивать JVM в ваше приложение и если да, то каким образом вы ее решали? И кстати, не знает ли кто-нибудь, насколько лицензия JVM вообще позволяет такое использование виртуальной машины, в частности, в коммерческих проектах?
Дополнение: В комментариях подсказывают, что также есть официальный пакеджер от Oracle . Размер инсталлятора получается от 39 Мб. Также советуют попробовать бесплатный Excelsior Installer . А тут можно прочитать небольшой пост про RoboVM на русском языке.