2014-07-23 31 views
5

Niedawno zobaczyłem online prezentację JRebela, w której wyjaśniają, co robi ich produkt, na jednym ze slajdów, o których wspominają, że nie używają programów ładujących klasy (zobacz zrzut ekranu poniżej).Jak dynamicznie ładować klasę Java bez użycia programu ładującego klasy?

Mam kilka projektów, w których korzystam z klas ładujących do dynamicznego ładowania klas w czasie wykonywania, na przykład w celu wstrzyknięcia zależności (tak jak w opracowanym przeze mnie środowisku Maker Factory). Sądziłem, że jedynym sposobem na załadowanie klasy w Javie było użycie programu ładującego klasy.

enter image description here

+0

podwójne sprawdzenie cytatu, mogliby napisać własną implementację i trochę pomalowani nad tym .. "nie używamy programu ładującego klasy jre" – edthethird

+0

Właściwie to gdzie przeczytałem, że było w pdf, że jeden z ich pracowników (próbuje przekonaj mnie, żebym użył/kupił produkt) do mnie wysłany, ale można go również znaleźć w: http://www.slideshare.net/boothdavid/how-can-jrebel-save-me-6-weeks-of-builds - i - redeploys - w tym roku na slajdzie numer 8, spróbuję też dodać zrzut ekranu do pliku pdf, który mam – raspacorp

Odpowiedz

3

Zastrzeżenie: Jestem związany z rozwojem JRebel

Technicznie możliwe jest ominięcie classloader z jakiejś magii uznanych za niebezpieczne, i że JVM korzysta z lambda przy tworzeniu środowiska wykonawczego klas anonimowych (w Java 8) .

Jednak JRebel faktycznie integruje się z istniejącymi programami ładującymi klasy i nie tworzy nowych - to jest to, co oznacza slajd. JRebel nie upuszcza istniejącego programu ładującego klasy, gdy musi ponownie załadować klasę. Zamiast tego ładuje i wersjonuje klasy w istniejących klasach ładujących.

+0

, więc używa on programu ładującego klasy? – edthethird

+0

Oczywiście korzysta z istniejących modułów ładujących klasy. W przeciwnym razie, jak mogłaby być wykonana aplikacja Java :) –

+0

ha prawo, więc odpowiedź na pytanie "Jak dynamicznie ładować klasę Java bez użycia programu ładującego klasy?" jest "Nie możesz, ale możesz ...". Co jest fajne, chciałem tylko wyjaśnić – edthethird

3

wspominają oni nie używać ładowarki klasy.

Każda klasa używa klasy Classoader (oprócz prymitywów). Jednak biblioteka nie musi tworzyć dodatkowej klasy ClassLoader.

nawet program „Hello World” będzie mieć dwie ładowarki (jeden dla boostrapping) Klasa

Myślałem, że jedynym sposobem, aby załadować klasę w Javie było przy użyciu programu ładującego klasy.

Jest, ale można zmusić istniejący program ładujący klasy do załadowania klasy, która jest hakerem, ale może być łatwiejsza w użyciu.

(Korekta) Jeśli użyjesz null jako ClassLoader, Unsafe.defineClass() domyślnie ustawi się na ClassLoader dzwoniącego.

0

Możesz oczywiście samemu odczytać plik klasy do pamięci. Ale aby klasa była dostępna w twoim kodzie, musisz nadal używać ClassLoader#defineClass.

Zasadniczo każda klasa używana w programie musi być zdefiniowana przez moduł ładujący klasy, w przeciwnym razie powinien powrócić getClass().getClassLoader().

1

Rzeczywiście, jedynym sposobem na załadowanie klasy jest ładowanie klasy.

Ludzie z JRebel prawdopodobnie chcieli powiedzieć, że nie używają klas ładujących , aby przedefiniować klasy. Przedefiniowanie klasy jest możliwe za pomocą innych środków, na przykład poprzez JVMTI.

3

Tak więc odpowiedź na to pytanie może być: Nie ma sposobu, aby załadować dynamicznie klasy Java bez korzystania z programu ładującego klasy po raz pierwszy. Ale możliwe jest przeładowanie klasy częściowo przez oprzyrządowanie programu ładującego klasy.

podstawie Dave Newtona linku odpowiedzi, wyodrębnianie ważnych rzeczy z FAQ JRebel:

one wykorzystać do instrumentu ładowarki klasy Instrumentation API kontener/Server, w ten sposób mogą dynamicznie monitorować i kontrolować proces ładowania. Będą skanować ścieżkę klasy w poszukiwaniu pliku .class, który odpowiada załadowanej klasie i użyć znacznika czasu pliku, aby wykryć zmiany na nim.Po wykryciu zmiany będą propagować tę zmianę za pomocą oprzyrządowanego programu ładującego klasy. Zachowa istniejące instancje klasy, ale nie uruchomi ponownie konstruktora, co oznacza, że ​​nowe dodane pola nie zostaną zainicjowane.