Ich versuche, die folgenden WRT refleciton, lassen Sie mich wissen, ob dies möglich istAbstractMethodError mit dynamischer Java-Kompilierung und das Laden von Klassen mit Reflexion
public class A {
void start(){
execute();
}
}
public class B extends A {
void execute()
{
doWork();
}
public abstract void doWork();
}
Ich habe die oben genannten Klassen in einem Glas verpackt und hat es auf einer Lauf JVM. Jetzt versuche ich eine andere Klasse zur Laufzeit zu erstellen, kompiliere sie zur Laufzeit und versuche mit Reflection die execute-Funktion von Klasse B aufzurufen().
public class C extends B {
@Override
public void doWork()
{
//Implementation
}
}
Reflection Code:
Classloader = Urls Anwendungs Gläser und URL C.class, zur Laufzeit zusammengestellt. Übergeordneter Loader - Thread.currentThread(). GetContextClassLoader() Ich setze auch den Context Class Loader des aktuellen Threads auf den oben erstellten Classloader.
Class<? extends B> cls = (Class<? extends B>) Class.forName("className", true, clsLoader);
Object obj = cls.newInstance();
Method method = obj.getClass().getSuperclass().getMethod("start", new Class[0]);
method.invoke(obj, new Object[0]);
Ich bin in der Lage, die Methode zu erhalten und ruft auch aufgerufen wird. Wenn jedoch die Ausführung der Klasse B aufgerufen wird, versucht sie, doWork() aufzurufen, und dann stosse ich auf einen AbstractMethodError. Wenn ich auf die Exception nachschaue, sehe ich, dass die Exception mit falschen Klassenlatern/Gläsern passiert. Aber ich bin mir nicht sicher, wie ich es in meinem Fall beheben kann.
Kann jemand helfen?
ich nur raten, aber ich glaube, der Klassenlader von C versucht, die abstrakte Methode der Klasse B zu finden, aber es hat keine Sicht davon, daher die abstrakte Methode Fehler. Persönlich vermeide ich die Reflexion um jeden Preis und wenn ich Code dynamisch laden möchte, benutze ich OSGi. Ich vermeide es auch, Code dynamisch zu erstellen. Zu viele Gefahren, vor allem Sicherheit, und ich glaube, Sie können mit einem vollständigen Rattennest Code – Kerry
@Kerry enden: der Klassenlader von 'C' hat keinen Grund, nach einer abstrakten Methode von' B' zu suchen. Es ist umgekehrt, wenn die abstrakte Methode von "B" aufgerufen wird, wird eine konkrete Implementierung in der Klassenhierarchie von "C" gesucht. Aber Sichtbarkeit ist in der Tat der Schlüssel hier. – Holger