Java ClassLoader ändern
Ich habe einige Klasse A
:
public class A {
public A(String str) {
System.out.println("Create A instance: " + str);
}
public void methodA() {
System.out.println("#methodA1()");
}
}
Und meine Klasse loader Umsetzung:
public class MyClassLoader extends ClassLoader {
public MyClassLoader() {
super();
}
@Override
public synchronized Class<?> loadClass(String name)
throws ClassNotFoundException {
System.out.println("Load: " + name);
return super.loadClass(name);
}
}
Und jetzt versuche ich zu ändern, Standard-class-loader im aktuellen thread:
import java.util.ArrayList;
import java.util.List;
public class ChangeLoaderTest {
public static void main(String[] args) {
//Save class loader so that we can restore later.
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
MyClassLoader newLoader = new MyClassLoader();
try {
//Set new classloader.
Thread.currentThread().setContextClassLoader(newLoader);
//My class.
A a = new A("1");
a.methodA();
//Standard Java class.
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(3);
} finally {
//Restore.
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
}
Sowie ChangeLoaderTest
Ausgabe:
Create A instance: 1
#methodA1()
Niemand
Load: ...
Warum? Wie ich das ändern kann ClassLoader
in einigen thread?
- "Ich habe einige Klasse Ein:" Während einige Leute denken, es ist besser, 'Abstrakt ein problem" auf den Punkt können Sie Ausdrücken, wie stumpf die Symbole, habe ich lieber ein paar Rahmen, der hilft, zu erklären, was in der Klasse
A
macht, die Sie laden möchten, ist es dynamisch. I. E. KlasseA
könnte einUserDefinedPlugIn
- letztere bietet einige Kontext, ersteres nicht. - Ok, ich kann das erklären Zusammenhang mit dieser Frage. Ich habe Klasse, die liest die Bilder in
BufferedImage
. Manchmal ist esImageIO.read(file)
, manchmal ist esSanselan.getBufferedImage(file)
. Ich habe meine eigene Klasse zum speichern von Bildern und ich müssteBuffredImage
aus Datei, dann kopieren Sie Daten ausBufferedImage
zu meinem Objekt. Ich möchte mit einigen proxy-Klasse, alle fangen#get(...)
Methoden aufrufen, um Daten zu speichern, die in meinem Objekt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als Marko Topolnik Punkte aus der Kontext-classloader ist für den Einsatz von frameworks. Die Verwendung der classloader selbst zu nennen
loadClass("somepackage.A")
und verwenden Sie dann die reflection-API zum erstellen einer neuen Instanz von A (Class.newInstance()
).Werden Sie nicht in der Lage sein zu verwenden oder Methoden in der Quelle direkt, da der aufrufende code nicht wissen - es verwendet einen anderen classloader. Eine Schnittstelle oder baseclass Eines geladen werden kann, die von der normalen classloader kann verwendet werden, um zu vermeiden, Reflexion.
Den
contextClassLoader
Mechanismen ist nicht eingesetzt, durch die grundlegende Java-Operationen wienew
. Es ist nur dazu da die verschiedenen frameworks können den Zugriff auf die context-class-loader in der Ladung und laden von Ressourcen, Klassen, etc. Java wird immer der classloader geladen, dass der code ausgeführt wird. Es ist das einzige, dass Sie überChangeLoaderTest.class.getClassLoader()
-- und es gibt nichts Sie tun können, über diese ein.Ich denke, dass das, was passiert ist, dass Ihre Anwendung der class-loader die auch Ihre classloader "Eltern" finden kann
A
und laden Sie es. Als Ergebnis Ihrer classloader nicht durchsucht werden oder zum ladenA
.Um ehrlich zu sein, ich habe nicht viel Erfahrung mit classloadern, aber wenn Sie Unterklassen verwendet eine URL für den Pfad der Klasse (so dass Sie es können suchen Sie die class-Datei) und die parent-classloader kann nicht geladen werden (nicht Teil des classpath), Ihre eigenen verwendet werden.