[updated 21/02/2021 ;-) niżej dodano wyniki dla Macbooka z M1 :-)]
Ostatnio musiałem dodać do kodu testy, które testują czy interfejs do bazy danych dobrze gada z DynamoDB.Zdecydowałem, że użyje lokalnego DynamoDB, które dostarcza AWS.
Problem w tym, że drań wymaga natywnych bibliotek na ścieżce...
A kod będzie uruchamiany na macOS, Windows i Linuksie ;-)
Stąd musiałem napisać kawałek, który rozpoznaje którą bibliotekę natywną umieścić na ścieżce.
Tutaj podzielę się czymś podobnym, a mianowicie tym jak różne OSy i czasem platformy sprzętowe się przedstawiają gdy pyta się je o to kim są z Java'y ;-)
Podstawą naszej zabawy będzie ten prosty programik:
public class Test {
public static void main(String[] args) {
System.out.println("OS Architecture : " + System.getProperty("os.arch"));
System.out.println("OS Name : " + System.getProperty("os.name"));
System.out.println("OS Version : " + System.getProperty("os.version"));
System.out.println("Data Model : " + System.getProperty("sun.arch.data.model"));
System.out.println("Endian : "+ System.getProperty("sun.cpu.endian"));
}
}
Tutaj opis tego co oznaczają poszczególne informacje.
OS Architecture (os.arch) - prostu architektura CPU i OSa (CPU może mieć często wyższą architekturę, ale uruchamiać kod dla "niższej" architektury). W przypadku Java'y będą to teraz głównie amd64 i x86_64 (obie znaczą to samo, ale zależą od OSa), czasem może się zdarzyć arm, z rzadka x86.
OS Name (os.name) - nazwa OSa, najbardziej "niepewna" część, macOS to np. czasem macOS, a czasem Darwin, Windows to czasem win, a czasem Windows. Jak jednak pokazują rezultaty, ostatnimi czasy jest jakiś porządek tutaj.
OS Version (os.version) - wersja OSa, chyba najmniej przydatna rzecz. Rzadko w Java'ie używamy wersji OSa do detekcji czekogolwiek.
Data Model (sun.arch.data.model) - bitowość Java'y :-) najmniej musi być 32, bo Java nigdy nie występowała w wersja 16 bitowej (przynajmniej nie znam takowej), teraz prawie zawsze 64. Ważna gdy ładuje się biblioteki natywne, bo 32 bitowy kod nie może być wykonany w trybie 64 bitowym, a 64 bitowy w trybie 32 bitowym.
Endian (sun.cpu.endian) - ciekawostka, "indianowatość" CPU. Tu jest ciekawe bo i x86 i ARMy są little endian, a sama Java jest big endian. Ogólnie w przypadku zapisu liczb w CPU, pamięci czy w pakietach przesyłanych siecią (albo w plikach) powstaje pytanie gdzie są które części liczby, czy bajt należy czytać od lewej czy prawej, czy słowo od prawej czy lewej i tak dalej. Kiedyś było to dość ważne, dziś żyjemy w świecie gdzie to wszystko jest zwykle dla nas załatwiane przez OS i biblioteki. Nasze OSy i CPU są little endian, sieć i Java big endian, a mimo wszystko to jakoś działa.
Sam programiki uruchomiłem na kilku konfiguracjach (z czego 3 to mój MBP 15 z macOS Catalina + Parallels 15)
Wyniki są takie:
Linux (Ubuntu 18.04, uruchomione przez Parallels 15 na macOS Catalina)
OS Architecture : amd64
OS Name : Linux
OS Version : 4.15.0-72-generic
Data Model : 64
Endian : little
Windows (Windows 10, uruchomione przez Parallels 15 na macOS Catalina)
OS Architecture : amd64
OS Name : Windows 10
OS Version : 10.0
Data Model : 64
Endian : little
macOS Catalina
OS Architecture : x86_64
OS Name : Mac OS X
OS Version : 10.15.2
Data Model : 64
Endian : little
Raspbian na Rasbperry Pi (Pi 2 Model B)
OS Architecture : arm
OS Name : Linux
OS Version : 4.1.19-v7+
Data Model : 32
Endian : little
Linux (Ubuntu 16.04)
OS Architecture : amd64
OS Name : Linux
OS Version : 4.4.0-170-generic
Data Model : 64
Endian : little
Android (Android Emulator w trybie x86 na macOS Catalina)
OS Architecture : i686
OS Name : Linux
OS Version : 4.14.112+
Data Model : null
Endian : null
Android (Pixel 3 XL z Androidem 10)
OS Architecture : aarch64
OS Name : Linux
OS Version : 4.9.185-xxxxx
Data Model : null
Endian : null
Macbook z M1 (dodane 21/02/2021)
Linux (Ubuntu 16.04)
OS Architecture : amd64
OS Name : Linux
OS Version : 4.4.0-170-generic
Data Model : 64
Endian : little
Android (Android Emulator w trybie x86 na macOS Catalina)
OS Architecture : i686
OS Name : Linux
OS Version : 4.14.112+
Data Model : null
Endian : null
Android (Pixel 3 XL z Androidem 10)
OS Architecture : aarch64
OS Name : Linux
OS Version : 4.9.185-xxxxx
Data Model : null
Endian : null
Macbook z M1 (dodane 21/02/2021)
OS Architecture : x86_64
OS Name : Mac OS X
OS Version : 10.16
Data Model : 64
Endian : little
Macbook z M1 (dodane 10/05/2021) - w końcu ARMa raportuje ;-)
OS Architecture : aarch64
OS Name : Mac OS X
OS Version : 11.2.3
Data Model : 64
Endian : little
OS Name : Mac OS X
OS Version : 11.2.3
Data Model : 64
Endian : little
Jak widać największe zamieszanie panuje w OS Architecture.
Na Windows i Linuksie pryz 64 bitach mamy amd64, ale na macOS X mamy x86_64.
Obie są prawidłowymi nazwami, choć x86_64 było nazwą zaproponowaną przez AMD gdy tworzyli ten tryb dla Athlonów, a amd64 powstało trochę później*.
Jeszcze kilka lat temu problemem była też "bitowość", czyli Data Model.
Wtedy sprawa się komplikowała, bo choć większość CPU na rynku była już 64 bitowa, to jednak OSy nadal były 32 bitowe. Później już i OSy i CPU były 64 bitowe, ale jeszcze soft był 32 bitowy.
Przez jakiś czas dostępne były wersje Java'y dla 64 bitowych OSów, które mogły pracować w 32 i 64 bitach.
Tutaj napiszę z pamięci, bo nie mam nigdzie żadnego 32 bitowego procesora zgodnego z x86, ani 32 bitowego OSa :-)
Ale jeśli dobrze pamiętam dla Windows to był x86, dla Linuksa i386 (czasem i586???), nie mam pojęcia jak było z macOS.
Na szczęście od paru lat wszystko co mamy ma prawie na 100% 64 bity (najnowsze Raspberry Pi 4 też jest 64 bitowe).
Kolejnym problemem jest OS.
Wydaje się jednak, że dziś można niemal na 100% przyjąć, że 1 słowo w lower case pozwoli na rozpoznanie OSa.
Widzimy też, że Android to tak naprawdę Linux ;-)
Oczywiście autorzy natywnych bibliotek nie zawsze przestrzegają reguł, stąd jeśli wiemy, że nasz kod będzie działał np. tylko na 64 bitowych wersjach macOS, Linuksa i Windows to prościej po prostu dokonywać detekcji OS'a i zamiast budować nazwę biblioteki, to po prostu mieć zahardcodowane wersje dla każdego z OSów.
Nie jest to najbardziej uniwersalna metoda, ale kod jest dużo prostszy ;-)
* - historia jest taka, że Intel uznał, że przejście na 64 bity to dobry moment na przejście na nową architekturę. Ale ponieważ była to nowa architektura, konieczna byłaby nowa licencja i dodatkowo trzeba by było tworzyć całkiem nowe procesory. Stąd AMD postanowiło wziąć istniejącą architekturę x86 i ją "zupgradować" do 64 bitów, tak jak kilka lat wcześniej zrobił Intel gdy dodał do 16 bitowego x86 32 bitowość.
Przez ten manewr, który pozwolił na w miarę szybkie przeniesienie kompilatorów i istniejącego kodu (nawet w assemblerze) na nową 64 bitową architekturę, x86_64 zabrał prawie cały rynek Itanium, który praktycznie umarł i żyje teraz tylko w highendowych procesorach od Intela, a i sam Intel planuje tę architekturę "umrzeć" w 2021 roku.
Podobne postybeta
Dla Java'y Apple Silicon M1 to jednak nadal x86 ;-)
W końcu dane z M1, które w Java'ie mówią, że to jest ARM :-)
"CPUInfo" w Java :-)
JNA, czyli w Java'ie też można :-)
Exif jest zły - część 2 :-)
Brak komentarzy:
Prześlij komentarz