W dniu dzisiejszym wszystkie tematy dotyczą Project Leyden i GraalVM, dlatego zamiast standardowego podziału postanowiłem przygotować jeden spójny tekst, w którym postaram się przeprowadzić Was przez wszystko to, co dzieje się w koło tych dwóch inicjatyw.
Tak jak miałem nadzieje tydzień temu – JavaOne nie rozczarowała. Co prawda dużych nowości nie było zatrzęsienie, ale dostaliśmy na przykład bardzo dobry Developerski Keynote, w ramach którego pokazano min. Helidon Nima czy nowości w ZGC. Do tych ostatnich planuje zresztą wrócić za tydzień, bo w świecie Garbage Collectorów znowu możemy spodziewać się ciekawych rzeczy. Dzisiaj jednak chciałem się skupić na czymś innym – prawdziwą bombą zrzuconą na nas w czasie konferencji była bowiem zapowiedź zmian w GraalVM. I bynajmniej nie chodzi tu o żadną rewolucje technologiczną.
Przez lata tym, co najbardziej blokowało adopcję GraalVM, był jego niejasny model licencyjny. O ile projekt alternatywnej dla JVM, uniwersalnej maszyny wirtualnej (jednej by wszystkimi rządzić 💍) zawsze mocno wiązał się z JDK w głowach programistów Javy, o tyle w praktyce relacja między tą dwójką nigdy nie była klarowna. W inny sposób się go rozwijało, inaczej był dystrybuowany, ale co najważniejsze – opierał się na zupełnie innej licencji niż OpenJDK. Zarówno wydanie społecznościowe (GraalVM Community Edition), jak i korporacyjne (GraalVM Enterprise Edition) pozostawały własnością Oracle.
W skrócie:
GraalVM rozwijany był w sposób mało transparentny, na boku i dopiero ostatnio zaczęto dbać o jego większą przejrzystość min. poprzez publikacje publicznej Roadmapy. Teraz okazuje się, że był to dopiero początek. Podczas wspomnianego już JavaOne ogłoszono bowiem, że Oracle oddaje GraalVM Community Edition w ręce społeczności, i takowe stanie się nareszcie częścią OpenJDK (Enterprise Edition pozostanie pod starą licencją).
Co to oznacza w praktyce? Początkowo nie wiedzieliśmy za wiele i w zasadzie całość publicznego ogłoszenia sprowadzała się do pojedynczego tweetu, bez większych szczegółów (trochę jakby w Oracle było wielu fanów sposobu komunikacji naszego rządu). Te jednak wreszcie się pojawiły. Do OpenJDK trafi cała specyfikacja Native Image i GraalVM-owego JIT-a dla Javy – pod starą licencją zostaną zaś implementacje GraalVM dla innych języków, takie jak Python, Ruby, R, i JavaScript. Cały proces rozwoju projektu zostanie też zunifikowany z tym, jak wydawane są nowe wydania JDK. W praktyce oznacza to więc dwa release do roku, LTS raz na dwa lata oraz JEPy. GraalVM stanie się więc realną częścią OpenJDK, z którą inne fragmenty projektu będą w stanie nareszcie wchodzić w realną synergię. Dotychczasowa historia takowej była bowiem bardzo, ale to bardzo wyboista.
Mało kto pamięta bowiem, że Java posiadała własny kompilator AoT od JDK 9, a GraalVM-owa implementacja JIT-a już kiedyś trafiła do OpenJDK 10. Obie funkcje zostały jednak usunięte poprzez ich znikomą adopcję – GraalVM, mimo niejasnego stanu licencyjnego pozostawał „kompletniejszą paczką”, gotową na produkcyjny ruch i wspieraną przez większość popularnych frameworków out-of-the-box. Z tego też powodu mało kto decydował się na gorzej wspierane, eksperymentalne funkcjonalności znajdujące się w OpenJDK. Teraz kiedy GraalVM staje się częścią używanej przez wszystkich Javy, ten rozjazd de facto znika… co ma bardzo ciekawe konsekwencje.
Osoby regularnie śledzące pracę nad JVM pewnie kojarzą nazwę Project Leyden. Problem z nim polega, że właściwie zrozumienie, czym tak naprawdę Leyden jest trudne. Mówi się o nim w bardzo różnych kontekstach – alternatywy dla GraalVM, kompilatora AoT, optymalizacji javowego JIT. Z tego powodu bardzo trudno jest zrozumieć, jaka jest jego misja i cel – i nie bardzo pomaga tutaj nawet oficjalny pitch projektu. W związku z tym Mark Reinhold, Chief Architect Javy, postanowił ten dyskurs nieco uporządkować, publikując tekst Selectively Shifting and Constraining Computation. Tytuł chyba został wybrany w konkursie na „Najmniej zachęcającą do lektury rzecz na świecie”, nie zmienia to jednak faktu, że naprawdę warto. Mark wchodzi w nim przez różne koncepcje na przesuwanie etapów kompilacji między poszczególnymi fazami działania programów JVM-owych, przy okazji tłumacząc, czym tak naprawdę jest właśnie to całe Ahead-of-Time, Just-in-Time, czy caching już skompilowanych fragmentów – jak Application Class Data Sharing czy Project CRaC. Tekst naświetla, czemu również w tej kwestii sprawdza się stare powiedzenie, że nigdy nie ma darmowych obiadów, a przy okazji wprowadza koncept Condenserów, na których główny nacisk będzie teraz stawiał Project Leyden. Condensery to z założenia transformatory aplikacji (np. z kodu źródłowego w bajt kod, z interpretowanego bajt kodu w kod kompilowany), którymi można swobodnie żonglować w procesie jej budowania i komponować w sposób optymalny dla naszej aplikacji. Cel – być w stanie wygenerować aplikację idealnie skrojoną pod środowisko uruchomieniowe, niezależnie czy jest to serwer aplikacyjny czy funkcja serverless/edge.
Oczywiście, wszystko co tutaj napisałem, jest sporym uproszczeniem uproszczeniem dla klarowności przekazu. Nie bez powodu Selectively Shifting and Constraining Computation czyta się te bite 15 minut 😉. Jeżeli zaś chcecie dostać bardzo ciekawą dyskusje na temat różnych tradeoffów, które mają kompilacje JIT i AOT, niedawno ukazała się na InfoQ prezentacja JIT vs. AOT: How to Pick the Right Approach, mająca formę panelu dyskusyjnego.
Dlaczego o tym piszę? Gdyż dobrze ukazuje to, dlaczego tak ciężko sklasyfikować Leyden, a równocześnie pozwala zrozumieć wiele działań projektu. Kiedy w czerwcu tego roku pojawiła się informacja, że Project Leyden opóźni prace nad kompilatorem AoT na rzecz optymalizacji JIT, nie oznaczało to więc całkowitego shift (hehe) projektu. Po prostu chwilowo koncentracja została przesunięta na innego Condensera. I tutaj właśnie przyszedł czas na powrót do oryginalnego tematu – wcalenie GraalVM do OpenJDK pozwala lepiej zintegrować go z Project Leyden. Prawdopodobnie GraalVM po prostu będziemy mogli traktować jako jeszcze jeden Condenser. Sprawi to też, że cały horyzont związany z kompilacją w JVM może wreszcie się trochę wyklarować.
Skacząc odrobinę w bok, ale tylko odrobinę, bo dalej w zakresie zainteresowań Project Leyden – dopiero co tydzień temu miałem okazję pisać o dołączeniu Google do Adoptium Working Group, a już mamy okazję zobaczyć pierwsze tego efekty. Adoptium poinformowało bowiem, że Google razem z Alibabą (chińską firmą stojącą za AliExpress) zaproponowało projekt Fast Startup Incubator. Jego celem są eksperymenty mające na celu wypracowanie sposobów na szybszy star Javowych aplikacji. Pod uwagę brane są zmiany w Application Class Data Sharing (o którym pisał Mark Reinhold w przywoływanym tekście), a także różne sposoby kompilacji Ahead-of-Time. Jak widać więc, temat jest bardzo gorący i wręcz bombardowani jesteśmy pracami z różnych kierunków. A powód jest bardzo jasny – ponownie są to chmury, Serverless i Edge Computing. Twórcom zarówno aplikacji, jak i chmur zależy, żeby Javy dało się jak najwygodniej używać w tym kontekście. Niezależnie od rankingu nie wypada ona w końcu z listy najpopularniejszych języków programowania.
A żeby zamknąć całość GraalVM, które pojawiło się w dniu dzisiejszym. Nowa wersja projektu o numerze 22.3 może pochwalić się wsparciem dla JDK 19 i jego masy eksperymentalnych featurów. Jest to między innymi Loom, do którego twórcy przygotowali specjalne demo superwydajnej implementacji Gry w Życie. Pojawił się również dostępny jeszcze w JDK 18 jwebserver
.
Ułtawione zostało również pobieranie GraalVM. Teraz wystarczy odpalić komendę
bash <(curl -sL https://get.graalvm.org/jdk)
aby pobrać aktualną wersję projektu. Może to być przydatne np. w środowisku CI. Dla wygody nas wszystkich, pojawiły się zaś nowe oficjalne Reachability Metadata dla takich projektów jak Hibernate, Jetty, Thymeleaf, JAXB.
Jeśli chodzi o internale, to tu też jest ciekawie. min. poprzez wsparcie jlink
czy nowa wersja Native Build Tools 0.9.15. Twórcy narzędzi otrzymali zaś nowe Native Image API, które pomóc ma na integracje narzędzi zewnętrznych z GraalVM.
Już na samo zakończenie, nie mogę nie wspomnieć o tym, że projekt otrzymał swoją własną maskotkę. Jest nią Grabbit i przyznam szczerze, jest ostatnią rzeczą która kojarzy mi się z Graal VM, ale ja ogólnie bardzo lubię, gdy projekty programistyczne mają maskotki… mocno więc propsuje.
Polecam lekturę samego postu releasowego, w którym twórcy chwalą się aktualizacjami dla środowisk uruchomieniowych innych niż Java, ale także poprawkami w samym kompilatorze.