Walka z wersją JDK w bashu – mały trik

Projekt używa kilku wersji Javy. Tak mniej więcej czterech, czyli od 6 do 9. Nic nadzwyczajnego, ale czasami mavenowi trzeba podstawić inne JDK. I tu zaczyna się robić ciekawie…

Listing 1. Domyślna konfiguracja JDK

$ echo $JAVA_HOME
/usr/lib/jvm/java-9-oracle

To nas nie zadowala z kilku różnych powodów. Maven co prawda ruszy, ale Java 9 poprzerzucała kilka przydatnych rzeczy i na przykład pluginy do generowania kodu nie za bardzo chcą działać. Jak sobie z tym poradzić?

Listing 2. Rozwiązanie proste

$ export JAVA_HOME=~/jdk-8

Tyle tylko, że jak będziemy chcieli coś zmienić, to znowu trzeba eksportować, a tu jeszcze dochodzą różne wydania w ramach „dużej” wersji języka. Można oczywiście to opędzić dodając odpowiedni skrypt i dodając go do $PATH! No nie…

Gdy uruchamiamy skrypt (proces) w bashu, to tworzona jest kopia wszystkich zmiennych środowiskowych i skrypt dział na tej kopii. Nie ma dostępu do zmiennych procesu rodzica. Inaczej mówiąc, jeżeli wykonamy kod z listingu 2 w skrypcie, to po zakończeniu skryptu, zmienna JAVA_HOME w aktualnej powłoce, będzie miała taką samą wartość jak przed wywołaniem skryptu.

To może aliasy? Aliasy mają to do siebie, że są rozwijane w ramach bieżącego procesu, ale nie mogą przyjmować parametrów. Można sobie zdefiniować kilka aliasów i mieć z głowy. Jeżeli jeszcze dodatkowo zautomatyzujemy tworzenie aliasów przy starcie powłoki, tak by opierając się na konwencji nazewniczej, generować alias per folder z JDK, to już miód. Osobiście ten pomysł nie przypadł mi do gustu. Bardzo mocny, ale ma pewną wadę. Jest zbyt dynamiczny jak na mój gust. Tak naprawdę nie wiem, co mam dostępne.

Opcją pośrednią jest zdefiniowanie funkcji w pliku .bashrc. Funkcja taka jest wykonywana w kontekście bieżącej powłoki. Mamy do niej dostęp i możemy ją swobodnie modyfikować.

Listing 3. Przykładowa implementacja.

use-java(){
    export JAVA_HOME=~/jdk-"$1"
}

Podsumowując, należy raz jeszcze wspomnieć, że skrypty (procesy) uruchamiane w powłoce są odseparowane od środowiska rodzica i nie mogą go zmieniać. Warto o tym pamiętać, bo pozwala, to na uniknięcie wielu uciążliwych błędów.

7 myśli na temat “Walka z wersją JDK w bashu – mały trik

  1. Albo możesz spróbować wykorzystać sdkman. Ja osobiście zrezygnowałem bo zauważyłem, że załadowanie tych wszystkich .profile i innych .bashrc zajmuje zauważalnie więcej czasu i stwierdziłem, że jednak aż tak często nie potrzebuje zmieniać wersji jdk, ale jak musisz żonglować tymi wersjami to może być jakieś rozwiązanie tym bardziej, że pobierze za Ciebie nową wersję 🙂

  2. Ło panie… toż to kobyła, ale… wygląda na całkiem przyjemną i chyba będzie rozkminiana, bo takie narzędzie jest przydatne jak prowadzisz szkolenia z tuningu JVMki i chcesz pokazać różnice pomiędzy wersjami.

  3. jEnv ciekawe, ale przykladowo taka jabba jeszcze zajmuje sie instalwoaniem jdk :
    https://github.com/shyiko/jabba

    Jednak, z tego co widze to bardziej ci przypasi toolchains, te ustawienia bedziesz miał w repo zakomitowane,
    ale to wymusi ewentualnie dodatkowe ustawienia w .m2.

    W praktyce używam jabby i toolchains jednoczesnie.

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax