Spis treści

Java 9: czy mogę stworzyć z mojej aplikacji binarkę?

Jakie mam opcje?

Chcę dać komuś mój programik. Nie mam pewności, czy ma zainstalowaną odpowiednią (tj. pozwalającą na uruchomienie mojego jara) wersję JRE. Myślę, że nie potrafi / nie chce / nie ma możliwości jej zainstalowania. Co mogę zrobić? Jak sobie poradzić?

Jako programista mogę przygotować temu komuś jeden plik - uruchamialnego jara. Do uruchomienia będzie oczywiście potrzebna zainstalowana w systemie Java (JRE) w wersji co najmniej takiej, jakiej użyłampodczas kompilacji (zależnie od opcji -source i -target).

Mogę też użyć istniejącyh “bundlerów”, które mogą utworzyć “instalator”, zawierający, oprócz mojego kodu, również cały Java Runtime Environment ważący około 300MB. Wady takiego rozwiązania są oczywiste:

  • paczka, którą dostarczę, będzie bardzo ciężka
  • uzależniam się od dostawcy “bundlera”, polegam na czyimś kodzie

Jak Java 9 rozwiązuje ten problem

Modularyzacja wprowadzona w Java 9 nie tylko umożliwia pisanie aplikacji modularnych. Oferuje również możliwość uwtorzenia dystrybucji aplikacji wraz ze środowskiem uruchomieniowym (JRE) ograniczonym wyłącznie do tych modułów biblioteki standardowej, z których rzeczywiście aplikacja korzysta.

Jak zrobić własną dystrybucję aplikacji

Aby stworzyć własną dystrybucję mojej aplikacji, użyję narzędzia jlink. Utworzy ono paczkę zawierającą:

  • skompilowany kod mojej aplikacji
  • środowisko uruchomieniowe (“minimalne”, czyli ograniczone do modułów, z których korzysta moja aplikacja)
  • skrypt uruchamiający aplikację (zależnie od systemu, skrypt bashowy w Linuksie albo batch dla Windowsa) przy pomocy “minimalnego” środowiska uruchomieniowego

Więcej o narzędziu jlink można przeczytać tutaj.

Moja pierwsza aplikacja

1
2
3
4
5
6
7
8
9
$ jlink\
--module-path mlib/\
--add-modules client,api,generator\
--output image\
--launcher cli=client/com.kamilachyla.Main\
--no-man-pages\
--no-header-files\
--compress 2\
--strip-debug\

Używam po kolei takich opcji:

  • --module-path mlib - wskazuję ścieżkę do katalogu z modułami
  • --add-modules client,api,generator - określam listę modułów mojej aplikacji
  • --output image - ustalam katalog docelowy, gdzie będą pliki dystrybucji
  • --launcher cli=client/com.kamilachyla.Main - definiuję nazwę (cli) skryptu uruchomieniowego oraz klasę główną wraz z nazwą modułu
  • --no-man-pages - nie chcę generowania podręcznika man
  • --no-header-files - nie potrzebuję plików nagłówkowych C
  • --compress 2 - chcę kompresować zasoby algorytmem ZIP
  • --strip-debug - nie potrzebuję symboli do debagowania

Wielkość katalogu z dystrybucją aplikacji

Katalog image ma wielkość 33M (jvm javy 14 to 438M).

1
2
3
4
5
$ du -sh image/
33M     image/

$ du -sh /usr/lib/jvm/java-14-openjdk-amd64/
438M    /usr/lib/jvm/java-14-openjdk-amd64/

Uruchomienie

Uruchamiam skrypt startowy w image/bin/cli - wszystko śmiga.

1
2
3
4
5
6
7
8
$ ./image/bin/cli
Generates single Rect with x=0, y=0 and given width and height
Rect[x=0.0, y=0.0, width=800.0, height=600.0]
Generates stream of squares with its side not smaller than 20
Rect[x=0.0, y=0.0, width=600.0, height=600.0]
Rect[x=600.0, y=0.0, width=200.0, height=200.0]
Rect[x=600.0, y=200.0, width=200.0, height=200.0]
Rect[x=600.0, y=400.0, width=200.0, height=200.0]

Źródła

Ship zero-dependency native app

Podobne artykuły

Mogą Cię również zainteresować: