piątek, marca 03, 2023

Szukanie czemu mi nie działa program na Java 17, a czemu działa na Java 8 ;-)

Niby programuję w Java'ie już około miliona lat ;-) [tak od września 2004 roku] widziałem już wiele, a to wersję JDK która nie miała jakichś metod w JDBC ;-), a to różne zachowanie tego samego GC na różnych maszynach.
Ale z biegiem czasu było tego coraz mniej.

A wczoraj zobaczyłem coś nowego :-)

Mam programik, który generuje "podobne posty" na blogu (to co widać na dole większości postów).
Działa on sobie tak, że odpala się co 15 minut na moim Raspberry Pi, pobiera posty z bloga, liczy podobne posty i jak jest na blogu inaczej niż wg niego powinno być to publikuje update postu.

Programik jest skompilowany dla JVM w wersji 8, bo taką kiedyś zainstalowałem Java'ę na Raspberry Pi.

Wczoraj przyszły do mnie 2 nowe ZimaBoard, z 8 GB RAM, i 4 rdzeniowymi Celeronami.
Zainstalowałem tam OpenJDK w wersji 17, skopiowałem JARa z RPi... uruchomiłem i się wywaliło na połączeniu sieciowym....

Dokładniej z:
java.net.ConnectException: Connection refused

To zacząłem sprawdzać ;-)

Najpierw, że coś jest nie tak z siecią na ZimaBoard.
Hipoteza: ZimaBoard ma źle skonfigurowany firewall

Sprawdziłem na moim macOS z tym samym JAR'em i zadziałało na Java 8, ale nie na 19 i nie na 17.
Ale jak z IJ w wersji 19 to działało ;-) [bo też klasy kompilowało].

OK, coś jest nie tak z JARem
Hipoteza: Format tego akurat pliku JAR działa dla 8, ale nie dla 17...

Zrobiłem JARa z wersją 8 z kodu, który mam w IntelliJ i działa... ale rozmiary są różne

Hipoteza: coś się zmieniło w bibliotece do połączeń sieciowych.

(nie twierdzę, że te hipotezy wynikają jedna z drugiej, tutaj wyraźnie zignorowałem to info o rozmiarze, chcąc sprawdzić coś innego)

Doszedłem już do czytania kodu JDK do PlainSocketImpl.c ;-) 
Ale uznałem, że to jednak nie jest dobry pomysł i porzuciłem na rzecz nowej hipotezy.

Hipoteza: pewnie coś się zmieniło w Java'ie i może jakieś security albo coś

(hipoteza z doświadczenia i tego, że na stack trace pojawiło się java.base/java.security.AccessController.doPrivileged)

Poszukałem (z ChatGPT ;-)) przełączników i nic, żaden nic nie zmienił.

Hipoteza: różna wersja biblioteki której używam do łączenia do Bloggera

(wracamy do tej obserwacji, że różni się rozmiar JARa)

Podmieniłem pliki z JARa (dokładniej rozpakowałem działającego i niedziałającego JARa i zacząłem podmieniać pakiety)

Dalsze zabawy pokazują, że jednak różnica może być w moim programie... (bawię się klasami i biorę zawartość działającego JARa, rozpakowuję i zmieniam pakiety by znaleźć kto się różni, i nawet wcześniej kdiff3 sprawdzałem i widziałem różnicę... czyli albo znaleźć trzeba źródła, albo spojrzeć na zdekompilowane wersje :-)).

OK, po dekomplilacji już wiem w czym problem :-) banalny jest :-)
Chociaż nie (ja to piszę jako strumień świadomości niemal ;-))

Bo widać, że jest różnica. Wersja, która działa na Java 8 i 17 ma https w adresach, a ta która działa tylko na Java 8 ma http....

Hipoteza: po pójściu na adres http, serwer wysyła 302 i Java 8 robi follow, a wyższe nie robią follow....

W kodzie mam teraz https://www.blogger.com/feeds/default/blogs, ale w starym jest http://www.blogger.com/feeds/default/blogs.

Jak sprawdziłem przy pomocy cURL'a jeśli udamy się do tego adresu z http to Google robi 302:
Location: https://www.blogger.com/feeds/default/blogs

No i wychodzi na to, że Java 8 robi follow, a Java 17 (10, 19... czyli pewnie wszystko powyżej Java 8) nie robi follow :-)

Wnioski:

To miał być taki zabawny post, że o coś się w Java'ie dziwnego dzieje ;-) a wyszła prezentacja mojego stylu rozwiązywania problemów ;-)
Co ciekawe byłem wcześniej w dobrej okolicy jak zacząłem się przyglądać temu PlainSocketImpl.c, ale uznałem, że nie warto i poszedłem dalej by wrócić do tego samego miejsca ;p

Lekcja na dziś - Java 8 robiła follow, a nowsze Java'y nie robią ;-)

Przydatne polecenia na dziś ;-)
java -p $(find . -name "*.class") - zrobi dekompilację wszystkich klas w katalogu aktualnym i wypisze na ekran... jak się przekieruje do pliku to mamy w pliku ;-)
curl -v - tryb verbose cURLa, dzięki temu widzimy 302 :-)
curl -L - tryb w którym cURL robi follow za 302 :-) (przy okazji gupi Postman robi zawsze follow i nie wiem jak zrobić by nie robił... spytałem ChatGPT i mi powiedział jak wyłączyć w Postman'ie "Automatically follow redirects") (przy okazji 2 ;-) curl -L -v robił follow ale też o tym pisze :-))

Tak przy okazji żeby się szybko przełączać między wersjami Java'y mam takie 2 polecenia w command line ;-)

list_java() {
/usr/libexec/java_home -V
}

setJava() {
export JAVA_HOME=`/usr/libexec/java_home -v $1`
}


Pierwsze, czyli list_java wypisuje mi wszystkie Java'y które mam zainstalowane na moim macOS, drugie wybiera tą która ma najbardziej podobną nazwę do tego co wpiszę ;-)

Czyli jak chcę Java'ę 8 to piszę setJava 1.8, jak chcę 17 to pisze setJava 17, jak wpisze setJava 1 to mi ustawia 19 ;-)

Przy okazji, list_java wypisuje mi takie ;-)
19.0.1 (x86_64) "Oracle Corporation" - "OpenJDK 19.0.1"
18.0.1 (x86_64) "Amazon.com Inc." - "Amazon Corretto 18"
18.0.1 (x86_64) "Azul Systems, Inc." - "Zulu 18.30.11"
17.0.6 (x86_64) "Amazon.com Inc." - "Amazon Corretto 17"
11.0.11.1 (x86_64) "Amazon.com Inc." - "Amazon Corretto 11"
11 (x86_64) "Oracle Corporation" - "Java SE 11"
10.0.2 (x86_64) "Oracle Corporation" - "Java SE 10.0.2"
1.8.0_292 (x86_64) "Amazon" - "Amazon Corretto 8"
1.8.0_202 (x86_64) "Oracle Corporation" - "Java SE 8"
1.8.0_181 (x86_64) "Oracle Corporation" - "Java SE 8"
1.8.0_92 (x86_64) "Oracle Corporation" - "Java SE 8"

Może warto by conieco było skasować ;-)





Podobne postybeta
Chumbawamba "Charlie" - wypijmy za Darwina :-)
Daj się zastąpić automatom... przynajmniej tam gdzie się to opłaci ;-)
W końcu dane z M1, które w Java'ie mówią, że to jest ARM :-)
Dla Java'y Apple Silicon M1 to jednak nadal x86 ;-)
Kto mi podmienia certyfikat do GMAILa? ;-) A bardziej - jak? ;-)

Brak komentarzy:

Prześlij komentarz