2009-12-17 10 views
32

mam jakiś kod, który wywołuje ..getClass(). GetClassLoader() ma wartość null, dlaczego?

x = getClass().getClassLoader(); 

ta zwraca null chociaż.

Po uruchomieniu tego samego kodu, nie z Eclipse, ale z wiersza poleceń, zwraca program ładujący klasy.

mogę włamać kod, aby to zrobić ...

if (getClass().getClassLoader() == null) 
{ 
x = ClassLoader.getSystemClassLoader().getSystemResourceAsStream(loadedPropFileName); 
} 

oba są kompilowane i uruchomić z tego samego JVM. (Jestem pewien na 99,99%).

Ktoś ma jakieś pomysły, dlaczego pierwszy zwróci wartość null dla programu ładującego klasy?

Edit:

Moje pytanie brzmi nie „Ktoś ma jakieś pomysły dlaczego ta sama klasa wróci NULL gdy uruchomiony poprzez Eclipse i ładowarki klasy kiedy załadowany z wiersza poleceń”

Dzięki za poradę, że program ładujący Bootstap musi ładować klasę w środowisku Eclipse. Nie mam pojęcia, dlaczego tak się dzieje.

Odpowiedz

30

Powołując się na API doc:

Niektóre implementacje mogą wykorzystywać null reprezentują ładującego klasy bootstrap. Ta metoda zwróci wartość null w takich implementacjach , jeśli klasa ta była załadowana przez moduł ładujący klasy bootstrap.

+3

To prawda, ale jeśli implementacja jest taka sama, dlaczego różne zachowanie w linii poleceń i Eclipse. Myślę, że właśnie o to OP naprawdę pyta ... –

+1

Jeśli chce wiedzieć coś innego niż to, o co prosi, dlaczego nie pyta o to, co naprawdę chce wiedzieć? – Bombe

3

Jedno jest pewne, Eclipse ma głębszą i bardziej skomplikowaną konfigurację klas ładujących niż w przypadku uruchamiania z wiersza poleceń. Jeśli widzisz różnice w sposobie, w jaki program ładujący klasy pojawia się w jednym kontraście, to jest to całkiem prawdopodobny powód.

nie jestem kompetentny w co dokładnie robi Eclipse, ale myślę, że jest bardzo prawdopodobne, że klasa jest nie ładowany przez bootstrap classloader gdy prowadzony od Eclipse ale Eclipse próbuje się wydawać tamtędy .

Bootloader ClassLoader jest statyczny po uruchomieniu aplikacji i nie można dodawać do niego słoików lub klas później, chyba że Eclipse nadpisał implementację ... w takim przypadku istnieje jeszcze inne możliwe wyjaśnienie.

0

Miałem ten sam problem. Ale rozwiązać go za pomocą: -

<ClassName>.class.getClass().getResource(urlString); 

Nadzieja to pomaga innym ...

7

Jak to działa. Ilekroć JVM próbuje załadować dowolną klasę, sprawdza poniżej warunków.

Jeśli klasa jest ładowana z Bootstrap ClassPath tj .; jdk \ jre \ lib \ rt.jar, BootStrap ClassLoader zostanie wywołany.

Jeśli klasa jest ładowana z rozszerzenia Ścieżka klasy tj .; jdk \ jre \ lib \ ext * .jar, zostanie wywołany Extension ClassLoader.

Jeśli klasa jest ładowana z aplikacji ClassPath aplikacji tj .; jak określono w zmiennej środowiskowej, wywoływana jest Application ClassLoader.

Ponieważ Bootstrap ClassLoader nie jest zaimplementowany w java, jest zaimplementowany w c lub C++, więc nie ma dla niego odniesienia, dlatego zwraca wartość null. Ale program ładujący klasy Extension i Application jest napisany w języku Java, więc otrzymasz odniesienie jako [email protected] i [email protected]

Tak więc, jeśli zrobisz coś takiego, System.out.println (String.class.getClassLoader()) otrzymasz wartość null, ponieważ ta klasa jest wywoływana przez BootStrap ClassLoader, Z drugiej strony, jeśli robisz to samo dla klasy w ścieżce Ext lub App Class otrzymasz odpowiednio: $ ExtClassLoader @ someHexValue i [email protected]

0

"Ta metoda zwróci wartość null w takich implementacjach, jeśli ta klasa została załadowana przez moduł ładujący klasy bootstrap." - JavaDoc w getClassLoader()

Program ładujący klasy zerowej jest zarezerwowany dla klas systemowych ze względów bezpieczeństwa i może być używany tylko wtedy, gdy Class.forName (nazwa String, inicjalizacja boolean, loader ClassLoader). Jeśli klasa ma zerową klasę ClassLoader, większość kontroli bezpieczeństwa nie jest wykonywana.