Dzisiaj temat mógł być tylko jeden – premiera JDK 20. Przejdziemy sobie przez to, co nowe wydanie przenosi, ale też nie przynosi.
1. JDK 20 wydane. Jakie JEPy zawiera?
Jej! Początkiem tygodnia mieliśmy premierę nowej Javy! Z jednej strony – duże wydarzenie (nie dość, że premiera nowego JDK, to jeszcze tak „okrągła”), z drugiej pisaliśmy o niej już tyle, że mam wrażenie iż sam fakt premiery jest de facto formalnością.
Kiedy poprzednia Java składała się głównie z Preview, przyznam, że było w tym coś fascynującego. W końcu to właśnie JDK 19 pozwalało nam spojrzeć w przyszłość tego, jak rozwijać się będzie platforma w najbliższych latach i posmakować wyników kilku długo oczekiwanych projektów. Muszę jednak przyznać, że ciężko wykrzesać mi jest podobny entuzjazm w stosunku do JDK 20. Ponownie mamy do czynienia z zestawem Preview, ale są to w zasadzie drobne iteracje (z wyjątkami o których za chwilę) już istniejących API. Widać, że wszystkie duże rzeczy czekają na JDK 21, o których niedawno pisaliśmy.
Finalnie więc lista nowości w JDK 20 prezentuje się następująco:
- 429: Scoped Values (Incubator)
- 432: Record Patterns (Second Preview)
- 433: Pattern Matching for switch (Fourth Preview)
- 434: Foreign Function & Memory API (Second Preview)
- 436: Virtual Threads (Second Preview)
- 437: Structured Concurrency (Second Incubator)
- 438: Vector API (Fifth Incubator)
Jak widzicie, zupełnie nowych rzeczy jest jak na lekarstwo. I oczywiście, sam fakt, że API w wersji preview przechodzą zmiany jest czymś pozytywnym, a takie dodatki w Foreign Function & Memory API są całkiem przyjemne – o nich możecie przeczytać choćby u Pera Minborga, który opublikował tekst Java 20: A Sneak Peek on the Panama FFM API (Second Preview). Nowa wersja Vector API jest zaś tak rewolucyjna, że w pierwszej wersji sami twórcy JDK zapomnieli go dołożyć do listy – nie zawiera żadnych nowych zmian. Jeżeli jesteście zaś ciekawi szczegółów zmian w proposalach nowych rekordów i pattern matchingu, o Record Patterns (Second Preview) oraz Pattern Matching for switch (Fourth Preview) pisałem już w jednej z poprzednich edycji. Podobnie wygląda sytuacje nowych iteracji JEPów powiązanych z Loomem – Virtual Threads (Second Preview) oraz Structured Concurrency (Second Incubator), które również miałem okazję już opisać. Nie robię tego tu po raz kolejny, bo nowości są naprawdę raczej kosmetyczne.
Od tamtego czasu, 437: Structured Concurrency (Second Incubator) doczekała się jednak pewnej zmiany, którą można uznać za jedyny realnie interesujący dodatek wprowadzony w JDK 20 – wsparcie dla Scope Values. I nimi się właśnie teraz zajmiemy.
O Scope Values
Zapotrzebowanie na lokalne wartości wynika ze zmian wprowadzonych w JVM na potrzeby Loom. Ze względu na fakt, że Loom opiera się na bardzo leciutkich wątkach (dzięki czemu możliwe staje się tworzenie ich w zasadzie nieograniczonej ilości), musimy bardzo uważać na rozmiar struktur tworzonych na potrzeby każdego wątku (bardzo fajny artykuł na ten temat znaleźć możecie tutaj).
Popularne Thread Locals (zmienne przypięte do wątku) od początku były kamieniem w bucie twórców wirtualnych wątków. Rozwiązaniem na nie mają być wspomniane Scope Values – efektywnie finalne, niemutowalne zmienne lokalne, które mogą być w ramach potrzeb bezpiecznie dzielone między wątkami, zmniejszając ilość niezbędnej pamięci. Każdy wątek-dziecko posiadać ma dostęp do pełnego kontekstu swojego rodzica. Pomysł realizacji tego zadania podkradziony został z Common Lispa i jego “zmiennych specjalnych”,
O Scope Values można myśleć jako niewidocznych parametrach, które są przekazywane do każdej metody. Mają one możliwość przypisania do zmiennej lokalnej wartości wyłącznie na potrzeby konkretnego zakresu (scope) – po jego zakończeniu wartości zmiennych w nim ustawionych zostanie automatycznie przywrócona. Zachowanie to pozwala np. na zakrycie wartości x i y, w którymś z “dzieci”, bez wpływu na wszystkie inne wątki je używające.
Dość dobrze obrazuje to kod źródłowy z JEPa:
final static ScopedValue<...> x = new ScopedValue<>();
final static ScopedValue<...> y = new ScopedValue<>();
{
ScopedValue.where(x, expr1)
.where(y, expr2)
.run(() -> ... code that uses x.get() and y.get() ...);
}
Jak widać, składnia przypomina trochę znane wszystkim “atomiki” na sterydach. Wartości x i y mogą być przekazywane z wątku “rodzica” do wątku “dziecka”. Metoda run() „wiąże” zaś w tym przypadku x i y z wartościami expr1 i expr2. Podczas wykonywania metody run() wszelkie wywołania x.get() i y.get() zwracają właśnie je. Po jej opuszczeniu, wartości wracają do wersji poprzednich, odziedziczonych po rodzicu.
Oczywiście, jak to z Loomem bywa, składnia może się jeszcze wielokrotnie zmienić (zwłaszcza, że mamy do czynienia z niczym innym jak inkubacją).
Źródła
Zainstaluj teraz i czytaj tylko dobre teksty!
2. Jednak JEP-y to jeszcze nie wszystko. O czym w kontekście JDK 20 pisze społeczność?
Czytając pierwszą sekcje tej edycji można by dojść do wniosku, że tak naprawdę nic w tej nowej Javie ciekawego nie ma. To nie jest do końca prawda, bowiem każde nowe wydanie poza samymi JEP-ami zwykle przynosi sporo mniejszych poprawek pod maską. Każdorazowo też pojawia się grupa bohaterów bez peleryn, którzy przynoszą dobrą nowinę i opowiadają o tych wszystkich dodatkowych rzeczach, które prawdodobnie nigdy nie przebiją się mocno do masowej świadomości.
Tak naprawdę najciekawszych z tekstów towarzyszących premierze nowego JDK napisał Nicolai Parlog – Developer Advocate Javy w Oracle – który w bardzo przekrojowy sposób rozłożył dla nas JDK 20 na czynniki pierwsze. Jego tekst o dość przewrotnym tytule Java 20 🥱 przeprowadza nas za rączkę min. po zmianach w funkcjach hashujących, zmianach związanych z JFR i JMX, czy też wsparciu dla Unicode 15.0. Takich mniejszych dodatków jest naprawdę sporo, dlatego sugeruje zerknąć na całość nawet jeśli zniechęciłem Was już do JDK 20 prezentowaniem „dużych” featurów. .
Programem podstawowym przy okazji każdego nowego wydania Javy jest tekst Thomasa Schatzla dotyczący zmian w Garbage Collectorach, nie inaczej jest w wypadku JDK 20. Z tekstu JDK 20 G1/Parallel/Serial GC changes dowiecie się, że o ile nie było żadnych godnych uwagi zmian w Serial GC, to już na przykład obiektów przez Parallel GC podczas Full GC została poprawiona przez wątki robotnicze obsługujące obiekty przekraczające ich lokalne regiony kompakcji, zmniejszając czasy pauzowania Full GC o 20% w wybranych przypadkach. W G1 zaś GC poprawiono przewidywania rozmiaru młodego pokolenia. Pozwala to na zmniejszenie przekroczenia czasu pauzy i pozwala na użycie większej liczby regionów młodego pokolenia na pojedyncze przejście GC, co pozwala na sumaryczne zmniejszenie ich ilości.
Wydanie JDK 20 zawiera kilka ulepszeń bezpieczeństwa, o czym śpieszy donosić Sean Mullan w JDK 20 Security Enhancements, kolejnej odłsłonie jego regularnie publikowanej serii. Nowe JDK które poprawiają domyślne zabezpieczenia platformy Java, zwiększają wydajność modułu Crypto i dodają nowe zdarzenia JFR do monitorowania bezpieczeństwa. Sean podkreśla też znaczenie faktu, że do API wyjątku InvalidParameterException
dodano nowe konstruktory, pozwalają na podanie przyczyny wystąpienia Exception. Sporo nowości doczekała się lista algorytmów szyfrowania w Javie, zawierając nowe pozycje, usprawnienia a także deprekacje.
Kolejną nowością jest wprowadzenie nowych właściwości systemowych i bezpieczeństwa, które kontrolują, które klasy mają prawo do rekonstrukcji obiektów z kontekstów JNDI/LDAP i JNDI/RMI. Warto podkreślić, że o ile propertiesy te są związane z security, nie należą bezpośrednio do obszaru bibliotek bezpieczeństwa.
Źródła
Zainstaluj teraz i czytaj tylko dobre teksty!
3. Ruch Docker wzbudza strach wśród społeczności Open-SOurce
A na koniec temat bardzo luźno związany z Javą, ale biorąc pod uwagę, jak dużo było dzisiaj kwestii związanych stricte JDK, a jest na tyle ciekawy, że stwierdziłem się nim podzielę.
Docker z bycia pupilkiem społeczności developerskiej, w ostatnich latach serią kilku kontrowersyjnych decyzji (które w skrócie można streścić jako „Pieniędzy by za pracę chcieli, kapitaliści paskudni”) zyskali sporo złej sławy. W ostatnim tygodniu do już istniejących kontrowersji dołożyła się zaś kolejna. Firma wysłał bowiem e-mail do wszystkich użytkowników Docker Hub, którzy utworzyli „organizację”, informując ich, że ich firma rezygnuje z planu Free Team, a konta, które nie zostaną migrowane zostaną usunięte. Wiadomość była przekazana w sposób mało empatyczny, bez próby wyjaśnienia co stanie się z istniejącymi w repozytorium zasobami. Nie ma się więc co dziwić, że decyzja Dockera o zakończeniu subskrypcji Free Team wywołała alarm w społeczności open-source.
Przykładowo, niektóre projekty starały się upewnić, że obrazy będą nadal dostępne dla społeczności. a mimo, że Docker napisał uspokajającego posta, przyznając się, że sposób komunikacji był „okropny”. W wyjaśnieniu firma tłumaczy, że przestarzały plan Free Team został zastąpiony przez program Docker-Sponsored Open Source, a żadne obrazy nie zostaną usunięte, to mleko już się rozlało. Na pewno jednak cała sytuacja na długi czas sprawi, że projekty OSS dwa razy zastanowią się nad wyborem swojego głównego repozytorium.
Przy okazji postanowiłem sprawdzić, jakie projekty powiązane z JVM-em są zakwalifikowane jako Sponsored OSS. Okazuje się, że jest tego trochę. Do tej kategorii należy min. Jenkins czy też OpenWhisk. Nieco zaskoczył mnie fakt, że np. taka Debianowa Liberica SDK, będąc obrazem mającym ponad 5 milionów pobrań, nie jest ani oficjalnym obrazem, ani nawet zweryfikowanym publikującym. Jest to o tyle zabawne, że BellSoft to twórcy wydanego w zeszłym roku Alpaquita Linux, czyli systemu operacyjnego szytego na miarę właśnie pod konteneryzacje.
A skoro już jesteśmy przy kontenerach, to jako fanatyk fok (jedna ma żywot na instagramie…) wspomnę, że testujemy ostatnio Podmana od RedHata, czyli alternatywę dla Dockera z najbardziej uroczym logiem w branży i muszę przyznać, że na razie sprawuje się naprawdę dobrze. Zwłaszcza lubię ich aplikacje desktopową, która nie odbiega niczym od Docker Desktop, a ma chyba nawet lepsze wsparcie Kubernetesa. Przy całej okazji całej afery z Dockerem dowiedziałem się zresztą, że posiadają też własne repozytorium obrazów.