Si vous ne pouvez pas compter sur Java Service Wrapper cité ci-dessus (par exemple, si vous êtes en cours d'exécution sur Ubuntu, qui n'a pas de version de paquet de SW), vous voudrez probablement le faire à l'ancienne: de votre programme d'écriture de son PID dans /var/run/$nom_du_programme.pid, et écrire un standard script d'initialisation SysV (par exemple utiliser l'un pour ntpd comme un exemple, c'est simple) autour d'elle. De préférence, faire LSB-conforme, trop.
Essentiellement, le début de la fonction teste si le programme est déjà en cours d'exécution (par des tests si /var/run/$nom_du_programme.pid existe, et le contenu de ce fichier est le PID d'un processus en cours d'exécution), et si pas exécuter
logfile=/var/log/$progname.log
pidfile=/var/run/$progname.pid
nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1
La fonction d'arrêt et de contrôles sur /var/run/$nom_du_programme.pid, teste si le fichier est le PID d'un processus en cours d'exécution, vérifie qu'il s'agit d'une machine virtuelle Java (afin de ne pas tuer un processus qui simplement réutilisé le PID d'un mort instance de mon Java démon) et puis tue le processus.
Lorsqu'il est appelé, ma méthode main() va commencer par écrire son PID dans le fichier défini dans le Système.getProperty("pidfile").
Un obstacle majeur: en Java, il n'est pas simple et standard pour obtenir le PID du processus de la JVM s'exécute.
Voici ce que j'ai:
private static String getPid() {
File proc_self = new File("/proc/self");
if(proc_self.exists()) try {
return proc_self.getCanonicalFile().getName();
}
catch(Exception e) {
/// Continue on fall-back
}
File bash = new File("/bin/bash");
if(bash.exists()) {
ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","echo $PPID");
try {
Process p = pb.start();
BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream()));
return rd.readLine();
}
catch(IOException e) {
return String.valueOf(Thread.currentThread().getId());
}
}
// This is a cop-out to return something when we don't have BASH
return String.valueOf(Thread.currentThread().getId());
}