2013-02-27 10 views
33

Używam środowiska Java w systemie OS X od wielu, wielu lat, a ostatnio, gdy Apple przestał domyślnie włączać Javę, pozwoliłem systemowi go uruchomić i zainstalować (dla mnie oczywiście).Zrozumienie środowiska Java w systemie Oracle na komputerach Mac

Więc teraz używam OS X 10.8 i muszę zainstalować Java 7, więc właśnie otrzymałem aktualizację 15 w formacie DMG i uruchomiłem instalator. Aktualizacje mojego/usr/bin/java (i powiązanych plików), aby wskazać tutaj:

/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java 

Tracing to z powrotem do wszystkiego '/System/Library/Frameworks/JavaVM.framework/Versions' albo punkty 'Obecna' lub "CurrentJDK", pierwszy z nich to link do "A" (który jest Oracle 7 Java, z tego, co wiem, nie wiem, dlaczego jest to "A"), a drugi jest linkiem do Java 6 Apple w "/ System /Library/Java/JavaVirtualMachines/1.6.0.jdk '.

To wszystko jest naprawdę mylące, ale to jeszcze nie jest moje pytanie. Wydaje się, że jest Java 7 zainstalowany tutaj:

/System/Library/Frameworks/JavaVM.framework/Versions/A 

Ale jest też Java 7 zainstalowany tutaj:

/Library/Java/JavaVirtualMachines/jdk1.7.0_15.jdk 

Znalezienie „java” w obu i drukując wersję daje tę samą wersję i build (java version "1.7.0_15"), jednak podczas mieszania plików są one różne.

Czy to oznacza, że ​​Oracle zainstalował Java 7 w dwóch różnych miejscach? Jeśli tak, dlaczego? Którego mam użyć? I dlaczego niektóre rzeczy wciąż wskazują na Java 6 (CurrentJDK).

Zajrzałem na stronę internetową Oracle, ale nic tam nie wyjaśnia niczego.

+0

Zadałem dokładnie to samo pytanie, które chcę. Byłem bardzo zdezorientowany przez "2" JRE w moim Macu. Twój opis jest jasny i czysty. Dzięki za pytanie :) –

Odpowiedz

56

JVM Oracle jest zainstalowany tylko w jednym miejscu. Zostałeś zwiedziony!

Jak już zauważyłeś, polecenia Java w /usr/bin są dowiązaniami symbolicznymi do plików binarnych w /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands. Pliki binarne w tym katalogu są aplikacjami pośrednimi, które określają, która maszyna wirtualna Java ma być używana *, a następnie wykonują odpowiedni plik binarny w tej wersji maszyny wirtualnej. Z tego powodu wszystkie pliki binarne o numerach /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands są prawie identyczne, mimo że można oczekiwać, że będą implementować zupełnie inną funkcjonalność.

Można to zobaczyć w akcji za pomocą dtrace:

[email protected]:~$ sudo dtrace -n 'syscall::posix_spawn:entry { trace(copyinstr(arg1)); }' -c "/usr/bin/java -version" 
dtrace: description 'syscall::posix_spawn:entry ' matched 1 probe 
dtrace: pid 44727 has exited 
CPU  ID     FUNCTION:NAME 
    8 619    posix_spawn:entry /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java 

danego dtrace wydruki procedury wywołania zewnątrz argumentu ścieżki do posix_spawn gdy jest ona wywoływana przez java -version. W moim przypadku program pośredniczący znalazł środowisko wykonawcze Java 1.6 w wersji /System/Library/Java/JavaVirtualMachines/1.6.0.jdk i wywołuje tę wersję polecenia java.

Pliki binarne mają także inną zaletę: po wykryciu, że nie zainstalowano żadnej maszyny wirtualnej Java, użytkownik poprosi o jej zainstalowanie.

chodzi o CurrentJDK dowiązania symbolicznego, najlepiej jak mogę powiedzieć, to dla zachowania wstecznej kompatybilności z przeszłości, kiedy Apple był jedynym źródłem JVM na OS X.


* Połączenie czynniki są brane pod uwagę przy ustalaniu, która maszyna wirtualna Java powinna być używana. JAVA_HOME jest używany, jeśli jest ustawiony (spróbuj JAVA_HOME=/tmp java).Jeśli nie ustawiono JAVA_HOME, odkryta zostanie lista wszystkich maszyn wirtualnych w systemie. Zmienne środowiskowe JAVA_VERSION i JAVA_ARCH są używane, jeśli są ustawione, do filtrowania listy maszyn wirtualnych do określonej wersji i obsługiwanej architektury. Wynikowa lista jest następnie sortowana według architektury (preferowana wersja 64-bitowa w stosunku do wersji 32-bitowej) i wersji (nowsze jest lepsze), a zwracana jest najlepsza wartość.

+1

Dziękuję bardzo, nawet nie pomyślałem, aby spojrzeć na rozmiar plików. Mogę zbadać nieco więcej na własną rękę, ale gdzie mówisz "aplikacje pośrednie, które określają, która maszyna wirtualna Java ma być używana" ... w jaki sposób dokonują tego ustalenia? Mam nadzieję, że jest z JAVA_HOME, ale może coś jeszcze? – rjcarr

+1

Uwzględniana jest kombinacja czynników. JAVA_HOME jest używany, jeśli jest ustawiony (spróbuj 'JAVA_HOME =/tmp java'). Jeśli parametr JAVA_HOME nie jest ustawiony, zostanie wykryta lista wszystkich maszyn wirtualnych w systemie. Zmienne środowiskowe JAVA_VERSION i JAVA_ARCH są używane, jeśli są ustawione, do filtrowania listy maszyn wirtualnych do konkretnej wersji i obsługiwanej architektury. Wynikowa lista jest następnie sortowana według architektury (preferowana wersja 64-bitowa w stosunku do wersji 32-bitowej) i wersji (nowsze jest lepsze), a zwracana jest najlepsza wartość. – bdash

8

Oracle Java 7 JRE (to znaczy taki, który jest wykorzystywany przez wtyczkę do przeglądarki internetowej i uruchomić apletów Java Web Start) instaluje się w /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home i jest to jeden, że wszelkie aktualizacje automatyczne wpłynie. The JDK (ten pobrany z http://www.oracle.com/technetwork/java/javase/downloads/index.html) instaluje się, tworząc katalog pod numerem /Library/Java/JavaVirtualMachines i sam musisz go zaktualizować. Możesz mieć wiele wersji JDK zainstalowanych obok siebie, ale tylko jeden "publiczny" JRE pod JavaAppletPlugin.plugin (który będzie odpowiadał ostatnio zainstalowanemu JDK lub nowszej wersji, jeśli był od tego czasu automatycznie aktualizowany).

Jak wyjaśnił bdash, komendy pod /usr/bin są odcinki, które przenoszą na którykolwiek JDK/JRE jest wskazywany przez zmienną środowiskową na JAVA_HOME, lub jeśli nie jest ustawiona, a następnie będą one wybrać najodpowiedniejszy Java do uruchomienia. Możesz użyć numeru /usr/libexec/java_home, aby sprawdzić, który z nich będą wybierać. Jeśli zostanie zainstalowana Java nie Java, wtyczki będą oferować instalację najnowszej wersji Java 6 (o ile wiem, że będą , a nie zaoferować instalację Java 7).

+0

Dzięki za wyjaśnienie i ma to sens. Będę musiał przetestować zmienną JAVA_HOME var i java_home bin, aby upewnić się, że mogę ją uruchomić zgodnie z oczekiwaniami. – rjcarr

+0

@rjcarr Zdaję sobie sprawę, że moja odpowiedź nie była całkowicie jasna - kody pośredniczące zawsze będą respektować JAVA_HOME - uruchomienie '/ usr/libexec/java_home' pokazuje, który z nich wybierze, jeśli JAVA_HOME nie jest _nie_ ustawiony. –

+1

@ bdash i Ian naprawdę docenili twoje odpowiedzi. Przybyłem do tego postu z RÓŻNEGO powodu, udało mi się zepsuć moją instalację w Javie przez zmasakrowanie/niezrozumienie różnych dowiązań symbolicznych i kodów pośredniczących. W przypadku, gdy inni dotkną tego problemu, moje błędy podczas działania mrówki są "java.lang.NoClassDefFoundError: Nie można zainicjować klasy sun.util.calendar.ZoneInfoFile, w sun.util.calendar.ZoneInfo.getTimeZone (ZoneInfo.java:663)" oraz "Wystąpił błąd wcześniej: java.lang.AsersertError: Platforma nie została rozpoznana w sun.nio.fs.DefaultFileSystemProvider.create (DefaultFileSystemProvider.java:73)" - Uff! –

Powiązane problemy