Frage

Ich schreibe eine Bibliothek, wo ich Menschen ermöglichen Implementierungen von bestimmten Schnittstellen zu schaffen, mit einem Plugin-Framework (es ist JPF, wenn Sie vertraut sind). Die Plugins sind nicht im Classpath gespeichert. Der Rahmen gibt mir ein Klassenladeprogramm für jedes Plugin, so dass, wenn Implementierung namens „MyImpl“ der Schnittstelle „MyInterface“ angefordert wird, ich das richtige Plugin zu finden, und um dann die Classloader des Plugins verwenden, um die Klasse zu laden, von dem ich eine Instanz machen kann wenn ich weiß etwas über den Konstruktor. So weit so gut.

Aber jetzt habe ich einen Fall, wo ich brauche eine Methode aufzurufen, die auf dieser speziellen Ausführung verfügbar ist. So gibt es zwei Möglichkeiten, die ich versuchen könnte, dies zu tun:

Methode 1:

// Makes sure that MyImpl has been loaded, using the custom classloader
Plugins.getClass(MyInterface.class, "MyImpl");
// This line will not compile because MyImpl is not available at build time
MyImpl foo = new MyImpl();
// If I could get this far, this line would work:
foo.methodOnlyInMyImpl();

Methode 2:

// This call will get an instance of MyImpl (already written and tested)
MyInterface foo = Plugins.getInstance(MyInterface.class, "MyImpl");
// Compiler error because there is no MyInterface.methodOnlyInMyImpl method.
foo.methodOnlyInMyImpl()

Methode 1 ist der Reiniger der beide, wie es am ähnlichsten ist, wie Sie den Code schreiben würden, wenn die Klasse „normal“ waren und nicht über ein Plugin zugänglich. Doch weder kompiliert.

Optionen ich mit so weit habe kommen:
A. Verwenden Sie Methode 2, aber die Verwendung Reflexion der methodOnlyInMyImpl Methodenaufruf zu tun (bitte, nein!)
B. Legen Sie die Plugin-Klassen in den Weg zu bauen und dann verwenden Sie Methode 1, die kompilieren würde. (Mein aktuelles Lieblings)
C. B +, wenn Plugins installiert sind, kopieren Sie die Klassendateien in ein anderes Verzeichnis, das in dem Classpath ist, so dass das System Classloader sie laden kann (verursacht andere Probleme)

Also, meine Fragen sind:

  1. Bin ich eine andere Idee fehlt, die besser ist?
  2. Wenn ich B zu tun, werde ich habe Probleme bei der Laufzeit? Schließlich wird die Klasse MyImpl mit vermutlich das System geladen wurden Classloader verwenden. Also, sobald es MyImpl foo sieht, wird es nicht versuchen MyImpl mit dem System Classloader zu laden, die fehlschlagen wird (auch wenn der Plugins.newInstance Aufruf eine Instanz von MyImpl bieten würde)?
War es hilfreich?

Lösung

Erstens, was Vorteil, den Sie aus dem Plugin-Mechanismus erhalten, wenn Sie gegen die reale Umsetzung implementieren müssen? Das Plugin sollte eine Schnittstelle implementieren und Sie die Implementierung über die Schnittstelle verwenden können.

Ich bin nicht fimilar mit JPF, aber Java-Klassen sind nie kompatibel, wenn sie von verschiedenen Classloader geladen. Aber es gibt zwei Möglichkeiten:

  1. Die Schnittstelle in Ihrem Classloader ist, hat das Plugin Classloader Ihre Klassenlader als Eltern, so seine Schnittstelle die gleiche wie bei Ihnen. Der Code 2 soll dies umgehen, wenn die Methode in der Schnittstelle decladed wird.

  2. Sie können die Serialisierung verwenden. Dies ist eine begrenzte Art und Weise nützliche transfering Datenobjekte zwischen unabhängigen Classloader. Ich brauchte diese für Quer Zusammenhang mit Anforderungsparametern zwischen zwei Webapps Dispatching zu verwenden.

Andere Tipps

Es gibt eine Bibliothek mit dem Namen TransLoader, die in einer früheren Frage erwähnt wurden. Hier ist die URL für die Quelle: http://code.google.com/p/transloader/.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top