web-dev-qa-db-fra.com

Modification d'un procédé à l'exécution par l'intermédiaire d'un mécanisme de permutation à chaud

Supposons que nous ayons un programme trivial Java qui se compose d'une seule classe:

public class HelloWorld {

   private static void replacable(int i) {
      System.out.println("Today is a Nice day with a number " + i);
   }        

   public static void main(String[] args) throws Exception {
      for(int i = 0; i < 100000; ++i) {
      replacable(i);
      Thread.sleep(500);
   }
}

Une fois compilé et exécuté, la sortie sera la suivante:

Aujourd'hui est une belle journée avec un numéro 0

Aujourd'hui est une belle journée avec un numéro 1

Aujourd'hui est une belle journée avec un numéro 2

Aujourd'hui est une belle journée avec un numéro 3

...

Ma question: existe-t-il (ou est-il à l'horizon) un moyen de permuter la méthode replacable lors de l'exécution? Quelque chose comme écrire une autre version de HelloWorld avec une nouvelle version de replacable, la compiler puis l'ancienne version dans une JVM déjà en cours d'exécution?

Donc, si j'écris la nouvelle version comme ceci:

private static void replacable(int i) {
   System.out.println("Today is an even nicer day with a number " + i);
}  

y a-t-il quelque chose de similaire à échange de code à chaud d'Erlang où je peux le faire:

  1. exécuter le programme d'origine
  2. écrire une version modifiée
  3. à l'aide d'un programme en ligne de commande, connectez-vous à la JVM en cours d'exécution et remplacez la méthode existante

de sorte que, pendant l'exécution, cela se produira:

Aujourd'hui est une belle journée avec un numéro 15000

Aujourd'hui est une belle journée avec un numéro 15001

Aujourd'hui est un jour encore plus agréable avec un numéro 15002

Aujourd'hui est un jour encore plus agréable avec un numéro 15003

...

Supposons que le programme ci-dessus soit autonome, s'exécute dans un environnement standard Java SE, il n'y a rien d'autre sur classpath, donc c'est presque un programme de style Hello world.

Remarque: je sais que des technologies comme la manipulation de bytecode ( cglib ), aspectJ , jRebel , JMX , le hotswapping des méthodes en Java EE etc. existe, mais ce n'est pas ce à quoi je pense. Pensez à Erlang.

56
darioo

Vous pouvez soit utiliser l'open source HotSpot VM ou le commercial JRebel IDE plugin pour atteindre facilement votre objectif (voir le tableau de comparaison - ici ).

38
Arun

Vous pouvez le faire via les chargeurs de classe. Par exemple, si vous connaissez des conteneurs Servlet comme Tomcat que les pages que vous les reload modifier dans le développement. Voici un grande explication de la création de code de dynamique en Java . Il explique non seulement le chargement, mais aussi la compilation de la source à la volée. Vous devriez être en mesure d'appliquer les concepts abordés à toute stratégie code rechargeant que vous souhaitez utiliser.

15
M. Jessup

Je l'ai utilisé cette tâche fourmi hotswap dans de nombreux projets. La cible Java peut être lancée via Ant, Eclipse, une invite de commande ou tout autre moyen tant qu'elle est lancée en mode débogage avec le port approprié ouvert. La page liée fournit des instructions sur comment faire via Ant.

Un nombre quelconque de classes peut être hotswapped tant que les changements ne sont pas structurels. Le corps de la méthode change généralement facilement avec le hotswap. Le code peut être hotswapped en exécutant un script ant via un shell ou Eclipse.

Au travail, j'utiliser un script qui hotswaps code change automatiquement en comparant les horodatages sur les fichiers de classe. Ceci est similaire à l'échantillon sur la page du projet qui montre un exemple simple qui hotswaps uniquement les classes modifiées.

Note complémentaire: Il utilise le système JPDA .

9
Andy

Un article un peu ancien, mais j'espère que quelqu'un trouvera cela utile:

J'ai trouvé le relativement récent Hotswap Agent est bien documenté et riche en fonctionnalités (et surtout, open source ).

3
aspiring_sarge

Vous pouvez le faire via l'interface JPDA (Java Platform Debugger Architecture): http://download.Oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap

Ce n'est pas automatique comme dans le cas d'Erlang - la JVM ne surveille pas le chemin de classe pour les modifications apportées aux fichiers de classe, puis les recharge et les relie en cas de modification, pour des raisons assez évidentes (Java a été conçu pour le déploiement Web, vous ne voulez pas interroger un http URL pour les changements).

2
Pete Kirkham

Vous pouvez utiliser le modèle de conception de stratégie, vous avez donc un objet à manipuler plutôt qu'une méthode, et un protocole de communication avec le programme pour lui dire d'utiliser un nom de classe donné comme classe de l'objet Strategy.

1
Raedwald

Et OSGi? L'échange à chaud est en quelque sorte "intégré" à la spécification - je pense que ce serait également une solution possible.

1
javamonkey79