72 votes

Comment charger un fichier jar au moment de l'exécution

M'a demandé de construire un système java que vous avez la possibilité de charger le nouveau code (expansion) lors de l'exécution. Comment puis-je re-charger un fichier jar alors que mon code est en cours d'exécution? ou comment puis-je charger un nouveau pot?

Evidemment, puisque la constante de temps est important, je tiens à ajouter la possibilité de re-chargement de classes existantes tout en elle (si elle ne compliquez pas les choses trop).

Quelles sont les choses que je devrais regarder dehors pour? (pensez à deux questions différentes - l'une concernant le rechargement des classes au moment de l'exécution, l'autre sur l'ajout de nouvelles classes).

79voto

Tom Hawtin - tackline Points 82671

Le rechargement de classes existantes avec les données existantes sont susceptibles de casser des choses.

Vous pouvez charger un nouveau code dans la nouvelle catégorie des chargeurs assez facilement:

ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { yourURL },
    getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();

Classe chargeurs qui ne sont plus utilisés peuvent être nettoyés (à moins qu'il y est une fuite de mémoire, comme c'est souvent le cas avec l'aide de ThreadLocal, les pilotes JDBC, java.beans, etc).

Si vous souhaitez conserver les données de l'objet, puis-je suggérer un mécanisme de persistance comme de la Sérialisation, ou ce que vous êtes habitué.

Bien sûr, le débogage de systèmes peuvent faire des choses plus, mais sont plus hacky et de moins en moins fiable.

Il est possible d'ajouter de nouvelles classes dans un chargeur de classe. Par exemple, à l'aide de URLClassLoader.addURL. Toutefois, si une classe ne parvient pas à charger (en raison, par exemple, vous n'avez pas ajouté), alors il ne sera jamais à la charge de la classe loader instance.

8voto

Thilo Points 108673

M'a demandé de construire un système java que vous avez la possibilité de charger le nouveau code lors de l'exécution

Vous pourriez vouloir à la base de votre système sur OSGi (ou au moins prendre un lot à elle), qui a été faite pour exactement cette situation.

Jouer avec les chargeurs de classe est vraiment difficile d'affaires, principalement du fait de la visibilité de classe fonctionne et que vous ne souhaitez pas exécuter difficiles à déboguer des problèmes plus tard. Par exemple, la Classe.forName(), qui est largement utilisé dans de nombreuses bibliothèques ne fonctionne pas trop bien sur la fragmentation du chargeur de classe de l'espace.

3voto

Amir Arad Points 2124

J'ai googlé un peu, et j'ai trouvé ce code ici :

 File file = getJarFileToLoadFrom();   
String lcStr = getNameOfClassToLoad();   
URL jarfile = new URL("jar", "","file:" + file.getAbsolutePath()+"!/");    
URLClassLoader cl = URLClassLoader.newInstance(new URL[] {jarfile });   
Class loadedClass = cl.loadClass(lcStr);   
 

Quelqu'un peut-il partager des opinions / commentaires / réponses concernant cette approche?

2voto

André Points 3224

En ce qui concerne le rechargement de classes existantes, prenez en compte cette question connexe:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X