Java : arrêter classe lancée - process memoire linux

Bonjour,
j’ai crée une classe qui fait office de serveur : Server.java
Afin de la lancer et de l’arreter , j’ai crée une autre classe : AdminServer.java qui contient 2 méthodes : start() et stop().
Admin contient aussi un ppté Server monServer
Dans start() je fais monServer = new Server();
et dans stop() : je fais monServer.stop();
Je crée un script (sous linux) qui lance Admin.start() et un autre qui lance Admin.stop() afin d’arrêter mon serveur.
Mais bien sûr, le stop() ne l’arrête pas, car la référence de monServer n’est plus la même. Comment faire pour avoir la bonne référence ?
Connaît on la référence d’un objet quand on le crée et ensuite, peut on le tuer d’ailleurs ?
J’avais aussi pensé à repérer (mais je ne sais pas comment en java) le numéro du process lors du start(). Enregistrer ce numéro dans un fichier, et lors du stop() : récupérer le numéro du process grace au fichier, et ensuite le tuer ( mais je ne sais pas la non plus comment en java ).
Avez vous une solution ?
Merci

Bonjour,
pour commencer on n’arrête pas une classe, mais un Thread:
Tu peux facilement lancer ta classe Server.java en le faisant implémenter “Runnable”, tu crée un Thread en passant en argument ton server, et tu lance ton Thread.

Tu peux tuer ton Thread au sein de la même jvm. mais pas en dehors: Je n’ai pas compris ce point, est-ce que tu souhaite relancer un 2ème process donc une autre jvm, ou est-ce que ton interraction peut avoir lieu dans la même jvm? C’est plus simple pour garder la référence, et ça évite de passe par un fichier ou autre bidouille :wink:

Pour tuer un Thread, tu fait Thrad.interrupt() (suspend est déprécié, il ne faut pas l’utiliser).
Mais selon la documentation Java, c’est mauvais, il vaut mieux positionner une variable dans la classe de ton Thread, et que le Thread s’arrête de lui-même. En remplaçant un while(true) par un while(! myBooleanStopped) par exemple.

Tuer le process Java ne terminera pas correctement ton server, d’ailleurs tu peux le faire facilement en Linux par un “kill -9 id” mais làa c’est plus du script linux la problématique.

En te relisant, je crois que tu veux classiquement une ligne de commande pour arrêter ton serveur, pour cela il faudrait “contacter” ton serveur: La solution que j’ai utilisé c’est une simple Socket qui ne fait qu’attendre sur le serveur, et qui dès qu’elle reçoit un N° “magique” prédéfinit, lance le propre arrêt du serveur au sein de la jvm.
Le client nécessaire à l’arrêt se contente alors de se connecter en local sur la socket et d’envoyer le N° “magique” attendu. Tu peux même le faire par telnet pour les tests: c’est plus simple à faire qu’à expliquer :smiley:

Merci, mais en effet, c’est relancer une autre jvm, et là, comment retrouver le bon Thread ? Peut on le stocker dans un fichier ? ça ne m’a pas l’air évident.
Ton idée de Socket me plait bien, même si je n’en ai jamais utilisée, donc je ne vois pas trop comment ça marche. Je vais chercher un peu en relisant ton message …

Alors qques questions sur ta socket :
tu la crée sur ton serveur, mais comment tu lui dis qu’elle attend un mot magique ?
Et ensuite, je suppose que sur le client, il crée une autre socket qui va se connecter sur la socket du serveur, et comment lui dit il le mot magique ?
J’espère que ce n’est que ça, et en effet, ce serait super comme solution …

Le mot magique, c’est juste pour éviter que quelqu’un d’autre te zappe ton serveur. une sorte de mot de passe.

Côté serveur:
http://java.sun.com/j2se/1.4.2/docs/api/index.html
dans un Thread (parce que accept est bloquant) tu fait un:


ServerSocket serverSocket = new ServeurSocket(65000);
while (true){
  socket = serverSocket.accept();
  int i =socket.getInputStream.read();
  if (i == MAGIC){
    otherThread.interrupt();//méthode propre
    System.exit(0);// méthode moyenne
  }
}


côté client:


Socket socket = new Socket("localhost",65000);
socket.getOutputStream.write(MAGIC);

Après tu peux le faire évoluer:

  • 65000 c’est un N° de port qui doit ête libre: de 1 à 65535, mais pas 23,25,80,110 donc à plus de 1000 tu es tranquille.
  • “localhost” c’est pour te connecter en local, mais là du coup, tu pourrait arrêter le server à distance en changeant ça.
  • les io: je n’envoie que du binaire, mais tu peux très bien mettre un flux ascii, et envoyer des infos intéressantes (un mot de passe complet, que sait-je encore)

les classes utilisées:
http://java.sun.com/j2se/1.4.2/docs/api/ja…rverSocket.html
http://java.sun.com/j2se/1.4.2/docs/api/ja…String,%20int)

Merci,
c pas mal, sauf que j’ai un problème, qui doit sûrement être logique, mais j’espère “fixable” …
En effet mon serveur, est en plus un service RMI, ce qui fait que quand je lance mon serveur avec ma socket, pas de problèmes, mais par contre si un de mes clients se connecte à mon serveur, via le service RMI, et bien c’est impossible, j’ai une exception du type : java.net.ConnectException : connection refused.
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java : 567)
alors que j’ai des numéros de port différents …
une idée docteur ?

arf, puisque tu as du rmi, tu aurait pu accéder au serveur en rmi au lieu de socket.:wink:
bon ben, essaye de N° socket différents, au cas ou il y ait de conflits.
Tu as bien fait le accept dans un Thread à part?

J’ai mieux relu ton message :sarcastic: , et j’ai mis ma socket dans un thread, et ça marche :super:
Merci pour tout !!!! :smiley:

et je ne voulais pas le faire via rmi, car le serveur fait pas mal de choses, et ce que le service rmi propose ne fait pas la totalité des fonctionnalités du serveur. Je ne voulais vraiment décoreller les 2