2009-11-05 19 views
6

Gibt es eine Möglichkeit, eine Java-Klassenimplementierung zu ersetzen, die bereits vom Systemklassenlader von einer anderen Implementierung geladen wurde (verfügbar als Array von Bytes)?Klassenimplementierung zur Laufzeit (Java)

meine Zweifel zu veranschaulichen, folgt diesem Code:

public class Main { 
    public static void main(String ... args) { 
     Foo foo = new Foo(); 
     foo.print(); 

     ClassLoader cl = ... 

     Foo foo2 = (Foo) cl.newInstance(); 
     foo2.print(); 
    } 
} 

Die print() Verfahren der ersten Foo prints "Implementation 1", wie der zweite prints "Implementation 2". Die zweite Instanz von foo wird vom Klassenlader aus einem Array von Bytes abgerufen (die in einer Datei gespeichert werden können oder aus einem beliebigen Stream stammen ...)

PS: Ist eine Anforderung, dass Foo eine Klasse ist, nicht eine Schnittstelle, und kann nicht erweitert werden, dh die tatsächlichen Bytes (innerhalb der VM), die die Klassenimplementierung definieren, werden überschrieben.

+0

Sind Sie sicher, dass Sie das wirklich wollen? Es wäre gut zu erklären, warum in der Frage. –

Antwort

0

CGLib macht solche Dinge. Es wird im Frühjahr & Hibernate für diesen Zweck verwendet.

0

Sie können einen Instrumentierungsagenten implementieren und java.lang.instrument.Instrumentation # redefineClasses (...) verwenden, um den Bytecode bereits geladener Klassen zu ersetzen.

4

Ja, das ist kein Problem. Sie sollten eine java.net.URLClassLoader verwenden. Zum Beispiel könnten Sie ihr eine URL geben, die ein Verzeichnis ist, in dem Ihre übergeordnete Foo.class Datei lebt.

Bearbeiten: Dann ist der Anruf, den Sie wollen, cl.loadClass("Foo").newInstance(). Sie können das Ergebnis nicht auf Foo übertragen, aber Sie können reflection verwenden, um die Methode print aufzurufen. Oder machen Sie Foo eine Unterklasse (oder Schnittstellenimplementierung) von etwas, das Sie nicht erneut implementieren werden, das eine print Methode definiert, und werfen Sie darauf um.

0

Ich verwende JMX zum Deimplementieren und die Klassen neu zu implementieren.