Puis-je décharger et recharger dynamiquement (autres versions du même fichier JAR)?
Je suis en train d'écrire un programme serveur qui est utilisé pour exécuter les tests unitaires d'une API
(afficher beaucoup d'informations et de fourniture d'accès web pour contrôler
/surveiller l'ensemble de la chose)...
Cette API est connu du serveur lors de la compilation et est fourni
comme un POT.
Pour être en mesure de comparer les résultats du test de l'unité de différentes versions
de l'API (sans redémarrer le serveur),
Je veux être en mesure de décharger le 'courant' version de l'API,
et pour recharger une nouvelle (ou ancienne).
Je ne veux pas utiliser URLClassLoader et d'appeler tous les
la méthode par le nom
( à l'aide de getDeclaredMethod("someMethod")
),
parce que le serveur dépend fortement de l'API, et il serait
compliqué à 'wrap' chaque appel de méthode dans une telle façon sale.
Je pensais: comme toutes les interfaces de tous versions du BOCAL
sont même, je n'ai pas pu le faire en quelque sorte le rechargement d'une autre version
du BOCAL (sans que le nom-invokation?).
Note: je suis en utilisant la dernière version de Java SE (6) et Java EE (5).
Si vous pensez, ce que je suis en train de réaliser n'est pas possible,
s'il vous plaît suggérer une "solution de contournement" ou un concept différent.
source d'informationauteur ivan_ivanovich_ivanoff
Vous devez vous connecter pour publier un commentaire.
Je pense que si vous chargez une classe à l'aide
(Javadoc ici), vous obtiendrez une instance de la classe fournie par le chargeur de classe. Tout chargé en raison de cette classe sera également chargé par la même classloader.
Aussi longtemps que vous êtes très prudent avec les objets instanciés à partir de ce point (pour le GC), vous devez être en mesure de recharger les différentes versions. Je l'ai fait une fois avant avec Java 1.3, il a fallu beaucoup de débogage, mais à la fin j'ai eu un "bootstrap" de l'application qui a chargé un
Runnable
classe par nom et a été en mesure de "soft-restart" par l'instanciation d'un chargeur de classe contre une autre URL et aller de nouveau.Vous pourriez par programmation à modifier votre classpath pour refléter votre POT de changements.
Voici comment j'allais le faire:
où jarfiles est la version de l'jar que vous souhaitez utiliser/remplacer.
Vous pouvez utiliser de l'open source du package : JclLoader qui aide dans le chargement des différentes versions d'un même pot. C'était aussi une nécessité dans l'une de nos systèmes pour faire des tests .
Lien: http://sourceforge.net/projects/jcloader/
OSGi est un cadre qui va vous permettre de le faire. JSR 277 Java Module System est conçu pour faire (je pense). Je n'ai pas suivi la OSGi -vs - JSR 277 débat, donc je ne sais pas f qu'ils essaient de marge.
Vous pouvez rouler avec classe chargeurs, mais ça va être moins "fun".
Oui. Je l'ai vu faire à un NFJS conférence. C'est la façon dont les choses comme les conteneurs web de support de déploiement à chaud des applications et consiste à prendre avantage de la portée de la classe chargeurs. Afin d'accomplir cela, vous devez créer un nouveau chargeur de classe et l'utiliser pour charger la bibliothèque en question.. puis jeter le chargeur de loin (ou pas) et de créer un autre lorsque vous souhaitez recharger. Vous pouvez également avoir à remplacer le comportement de la classe loader (je me souviens de quelque chose à propos de la classe des chargeurs d'obtenir des classes par l'intermédiaire de leurs parents en premier par défaut.) Aussi, je me souviens d'un avertissement que les objets créés par les différents chargeurs de classe sont pas compatible (pas du même type), les uns avec les autres, même si l' .fichier de classe est exactement le même.
C'est surtout profonde de la magie pour moi si. 😉
Probablement pas. La Java du chargeur de classe n'a pas vraiment de soutien au moment de l'exécution de chargement; même la disposition des chargeurs de classes sont des hacks que l'utilisation d'un objet proxy.