Question

Je suis en train d'écrire une bibliothèque où je permets aux gens de fournir des implémentations de certaines interfaces à l'aide d'un cadre de plug-in (il est JPF si vous connaissez). Les plug-ins ne sont pas stockés dans le classpath. Le cadre me donne un ClassLoader pour chaque plug-in, donc quand la mise en œuvre nommée « MyImpl » de l'interface « MyInterface » est demandée, je peux trouver le plug-in correct, et ensuite utiliser le ClassLoader de ce plug-in pour charger la classe, à partir de laquelle je peux faire une instance si je sais quelque chose au sujet du constructeur. Jusqu'à présent, si bon.

Cependant, maintenant j'ai un cas où je dois appeler une méthode qui est disponible uniquement sur cette mise en œuvre particulière. Donc, il y a deux façons je pourrais essayer de le faire:

Méthode 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();

Méthode 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()

Méthode 1 est le plus propre des deux, car il est plus semblable à la façon dont vous écrivez le code si la classe était « normale » et non accessible via un plug-in. Cependant, ni compile.

Options Je suis venu avec jusqu'à présent:
A. Utilisez la méthode 2, mais la réflexion de l'utilisation à faire l'appel de méthode methodOnlyInMyImpl (s'il vous plaît, non!)
B. Placez les classes de plug-in dans le chemin de génération et puis utilisez la méthode 1, qui compilerait. (Mon préféré actuel)
C. B + lorsque les plugins sont installés, copiez les classfiles dans un autre répertoire qui est dans le chemin de classe, de sorte que le classloader système peut les charger (d'autres problèmes provoque)

Alors, mes questions sont:

  1. Est-ce que je manque une autre idée qui est mieux?
  2. Si je fais B, je vais avoir des problèmes lors de l'exécution? Après tout, la classe en utilisant MyImpl sera probablement avoir été chargé à l'aide du système classloader. Ainsi, dès qu'il voit MyImpl foo, il ne sera pas essayer de charger MyImpl en utilisant le chargeur de classes du système, qui échouera (même si l'appel Plugins.newInstance fournirait une instance de MyImpl)?
Était-ce utile?

La solution

D'abord, quel avantage vous obtenez du mécanisme de plug-in, quand vous avez besoin de mettre en œuvre contre la mise en œuvre réelle? Le plug-in doit implémenter une interface et vous pouvez utiliser la mise en œuvre via l'interface.

Je ne suis pas femblable avec JPF, mais les classes Java ne sont jamais compatibles lorsqu'ils sont chargés par différentes classloaders. Mais il y a deux façons possibles:

  1. L'interface est dans votre classloader, le plug-in classloader a votre classloader en tant que parent, de sorte que son interface est la même que la vôtre. Le code 2 devrait fonctionner avec cela, lorsque la méthode est decladed dans l'interface.

  2. Vous pouvez utiliser la sérialisation. Ceci est une façon limitée des objets plus données entre transfering USEFULL classloaders indépendants. Je devais l'utiliser pour l'envoi contexte international avec le paramètre de demande entre deux webapps.

Autres conseils

Il y a une bibliothèque appelée TransLoader qui a été mentionné dans une question précédente. Voici l'URL de la source: http://code.google.com/p/transloader/.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top