2009-12-17 2 views
32

Ho un po 'di codice che chiama ..getClass(). GetClassLoader() è null, perché?

x = getClass().getClassLoader(); 

Questo restituisce nulla però.

Quando avvio lo stesso codice non da Eclipse, ma dalla riga di comando, restituisce un classloader.

posso hackerare il codice per fare questo ...

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

entrambi sono compilato ed eseguito con la stessa JVM. (Sono sicuro al 99,99%).

Qualcuno ha qualche idea del perché il primo restituirebbe null per il classloader?

Edit:

La mia domanda è fa "Qualcuno ha qualche idea per cui la stessa classe sarebbe restituire NULL quando viene avviato tramite Eclipse e un caricatore di classe quando caricata dalla riga di comando"

Grazie per il consiglio che il caricatore Bootstap deve caricare la classe in Eclipse. Non ho idea del perché questo accada però.

risposta

30

Citando il API doc:

Alcune implementazioni possono utilizzare null per rappresentano il caricatore di classe bootstrap. Questo metodo restituirà null in tali implementazioni se questa classe è stata caricata dal caricatore di classe bootstrap.

+3

Vero, ma se l'implementazione è la stessa, perché il diverso comportamento in riga di comando ed Eclipse. Penso che questo sia ciò che l'OP sta davvero chiedendo ... –

+1

Se vuole sapere qualcosa di diverso da quello che sta chiedendo, perché non chiede quello che vuole veramente sapere? – Bombe

3

Una cosa è certa, Eclipse ha una configurazione del classloader più profonda e complicata rispetto a quando si esegue dalla riga di comando. Se stai vedendo differenze nel modo in cui il classloader di una classe appare in uno rispetto all'altro, allora è una ragione abbastanza probabile.

Io non sono esperto in che cosa esattamente Eclipse sta facendo, ma penso che sia molto probabile che la classe è non essere caricato dal classloader di bootstrap quando viene eseguito da Eclipse, ma che Eclipse sta tentando di far sembrare quel modo .

Il bootstrap ClassLoader è statico una volta che l'applicazione è stata sottoposta a bootstrap e non è possibile aggiungere jar o classi in un secondo momento a meno che Eclipse non abbia sostituito l'implementazione ... nel qual caso, c'è un'altra possibile spiegazione.

0

Ho avuto lo stesso problema. Ma risolto utilizzando: -

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

Spero che questo aiuta gli altri ...

7

Questo è come funziona. Ogni volta che JVM tenta di caricare qualsiasi classe, controlla le condizioni sotto riportate.

Se Class viene caricato da Bootstrap ClassPath i.e; jdk \ jre \ lib \ rt.jar, verrà chiamato ClassLoader BootStrap.

Se Class viene caricato da Extension Classpath i.e; jdk \ jre \ lib \ ext * .jar, verrà chiamato Extension ClassLoader.

Se la classe viene caricata dall'applicazione ClassPath i.e; come specificato in Variabile d'ambiente, viene chiamato ClassLoader dell'applicazione.

Poiché Bootstrap ClassLoader non è implementato in java, è implementato in c o C++, quindi non esiste alcun riferimento per questo motivo è che restituisce null. Ma l'estensione e il caricatore della classe Application sono scritti in java, quindi otterrai il riferimento come [email protected] e [email protected]

Quindi, se si fa qualcosa di simile a questo System.out.println (String.class.getClassLoader()) si otterrà null poiché questa classe è stata chiamata da BootStrap ClassLoader, D'altra parte se si fa lo stesso cosa per una classe in percorso Ext o App Class otterrai $ ExtClassLoader @ someHexValue e [email protected] rispettivamente.

0

"Questo metodo restituirà null in tali implementazioni se questa classe è stata caricata dal caricatore di classe bootstrap." - JavaDoc in getClassLoader()

Il programma di caricamento classe null è riservato alle classi di sistema per motivi di sicurezza e può essere utilizzato solo se Class.forName (nome stringa, inizializzazione booleana, caricatore ClassLoader). Se una classe ha un ClassLoader null, la maggior parte dei controlli di sicurezza non viene eseguita.