Il n'existe aucun moyen indépendant de la plateforme qui puisse être garanti de fonctionner dans toutes les implémentations jvm.
ManagementFactory.getRuntimeMXBean().getName()ressemble à la meilleure solution (la plus proche). Il est court et fonctionne probablement dans toutes les implémentations largement utilisées.
Sur linux + windows, il retourne une valeur comme 12345@hostname( 12345étant l'identifiant du processus). Attention cependant selon les documents , il n'y a aucune garantie sur cette valeur:
Renvoie le nom représentant la machine virtuelle Java en cours d'exécution. La chaîne de nom renvoyée peut être n'importe quelle chaîne arbitraire et une implémentation de machine virtuelle Java peut choisir d'incorporer des informations utiles spécifiques à la plateforme dans la chaîne de nom renvoyée. Chaque machine virtuelle en cours d'exécution peut avoir un nom différent.
Vous pouvez utiliser JNA . Malheureusement, il n'y a pas encore d'API JNA commune pour obtenir l'ID de processus actuel, mais chaque plate-forme est assez simple:
Sous Java 9, la nouvelle API de processus peut être utilisée pour obtenir l'ID de processus actuel. Commencez par saisir un descripteur du processus en cours, puis interrogez le PID:
+1 Mais je crains que dans un environnement à sécurité limitée, cela ne fonctionne pas (tomcat, WebLogic, etc.).
ATorras
La getpid()solution fonctionne également pour OS X, avec un appel JNA à la bibliothèque "System".
Daniel Widdis
Cependant, je reçois error: cannot find symbolpour jdk9
skytree
56
Voici une méthode de porte dérobée qui pourrait ne pas fonctionner avec toutes les machines virtuelles mais devrait fonctionner à la fois sur Linux et Windows ( exemple original ici ):
très sympa, vient de vérifier qu'il fonctionne aussi bien sur les JRockit que sur les JVM Hotspot.
Drupad Panchal
1
Belle solution de contournement. Je vais supposer qu'il y a une bonne raison pour laquelle cette méthode (et d'autres dans la classe) n'est pas publique et facilement accessible, et je suis curieux de savoir de quoi il s'agit.
fragorl
2
L'équipe Oracle Oracle a annoncé son intention de masquer tous les packages non java (c'est-à-dire sun. *) Je crois à partir de Java 10 (prévu pour 2018 - peut-être Java 9). Si vous avez une implémentation similaire à celle ci-dessus, vous voudrez peut-être trouver une alternative pour que votre code ne se casse pas.
hfontanez
Ne fonctionne pas pour moi non plus car le soleil. * Les packages sont probablement supprimés ou inaccessibles (VMManagement ne peut pas être résolu en un type).
Mike Stoddart
En raison du fonctionnement de la réflexion, l'accès à sun.management. * N'est pas nécessaire. Il suffit d'effectuer la getDeclaredMethodsur l'objet retourné par jvm.get(runtime).
Andrew T Finnell
36
Essayez Sigar . API très étendues. Licence Apache 2.
Vous auriez beaucoup plus de votes positifs si vous expliquiez comment utiliser SIGAR pour cela
Brad Mace
1
Le lien est rompu. Vous donnez un exemple d'utilisation, mais existe-t-il une dépendance maven pour cela?
Jules
github.com/hyperic/sigar semble être un emplacement utilisable; cela montre également que c'est du code natif avec des liaisons Java, ce qui peut le rendre moins une solution pour de nombreux contextes.
Zastai
26
La méthode suivante tente d'extraire le PID de java.lang.management.ManagementFactory:
privatestaticString getProcessId(finalString fallback){// Note: may fail in some JVM implementations// therefore fallback has to be provided// something like '<pid>@<hostname>', at least in SUN / Oracle JVMsfinalString jvmName =ManagementFactory.getRuntimeMXBean().getName();finalint index = jvmName.indexOf('@');if(index <1){// part before '@' empty (index = 0) / '@' not found (index = -1)return fallback;}try{returnLong.toString(Long.parseLong(jvmName.substring(0, index)));}catch(NumberFormatException e){// ignore}return fallback;}
VisualVM utilise un code similaire pour obtenir son PID, consultez com.sun.tools.visualvm.application.jvm.Jvm # ApplicationSupport # createCurrentApplication (). Ce sont les experts, il ressemble donc à une solution fiable et multiplateforme.
Espinosa
@Espinosa VisualVM prend uniquement en charge l'exécution sur une machine virtuelle Java OpenJDK / Oracle / GraalVM (à partir de 2020). Cela signifie qu'ils peuvent faire des hypothèses en conséquence. Si vous faites de même, vous devenez dépendant du fournisseur et votre code peut se casser s'il est exécuté par exemple sur J9.
Thorbjørn Ravn Andersen
24
Pour les anciennes JVM, sous Linux ...
privatestaticString getPid()throwsIOException{byte[] bo =newbyte[256];InputStream is =newFileInputStream("/proc/self/stat");
is.read(bo);for(int i =0; i < bo.length; i++){if((bo[i]<'0')||(bo[i]>'9')){returnnewString(bo,0, i);}}return"-1";}
Si vous allez faire cela, alors faites-le int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());. Pourquoi les girations supplémentaires?
David Citron
2
Pour les curieux, l'astuce dans le commentaire de @David fonctionne réellement. Quelqu'un peut-il dire pourquoi? Une sorte de magie dans la getCanonicalFile()méthode qui convertit le «moi» en PID?
@DavidCitron +1! vous avez raison, je ne pensais pas dans getCanonicalFile :-)
ggrandes
18
Vous pouvez consulter mon projet: JavaSysMon sur GitHub. Il fournit un identifiant de processus et un tas d'autres choses (utilisation du processeur, utilisation de la mémoire) multiplateforme (actuellement Windows, Mac OSX, Linux et Solaris)
Pouvez-vous expliquer comment obtenir une instance de processus pour le processus en cours d'exécution dans Java 9?
Augusto
Excellente réponse pour utiliser Java 9 en 2016! Pouvez-vous ajouter un lien vers les javadocs? merci
crazyGuy
8
À Scala:
import sys.process._
val pid:Long=Seq("sh","-c","echo $PPID").!!.trim.toLong
Cela devrait vous fournir une solution de contournement sur les systèmes Unix jusqu'à la sortie de Java 9. (Je sais, la question concernait Java, mais comme il n'y a pas de question équivalente pour Scala, je voulais laisser cela aux utilisateurs de Scala qui pourraient tomber sur la même question.)
Le dernier que j'ai trouvé est qu'il existe une propriété système appelée sun.java.launcher.pidqui est disponible au moins sur Linux. Mon plan est de l'utiliser et s'il n'est pas trouvé d'utiliser le JMX bean.
Dans mon cas avec Ubuntu 16.04 et Java 8, il renvoie null
david.perez
4
Cela dépend d'où vous cherchez les informations.
Si vous recherchez les informations de la console, vous pouvez utiliser la commande jps. La commande donne une sortie similaire à la commande Unix ps et est livrée avec le JDK car je crois que 1.5
Si vous cherchez à partir du processus, le RuntimeMXBean (comme l'a dit Wouter Coekaerts) est probablement votre meilleur choix. La sortie de getName () sous Windows à l'aide de Sun JDK 1.6 u7 se présente sous la forme [PROCESS_ID] @ [MACHINE_NAME]. Vous pouvez cependant essayer d'exécuter jps et d'analyser le résultat à partir de cela:
String jps =[JDK HOME]+"\\bin\\jps.exe";Process p =Runtime.getRuntime().exec(jps);
S'il est exécuté sans options, la sortie doit être l'ID du processus suivi du nom.
L'outil JPS utilise la bibliothèque jvmstat, qui fait partie de tools.jar. Consultez mon exemple ou consultez le code source JPS: grepcode.com/file_/repository.grepcode.com/java/root/jdk/… . Il n'est pas nécessaire d'appeler JPS en tant que processus externe, utilisez directement la bibliothèque jvmstat.
Espinosa
4
Il s'agit du code JConsole et potentiellement utilisé par jps et VisualVM. Il utilise des classes de
sun.jvmstat.monitor.*package, de tool.jar.
La tool.jarest une bibliothèque distribuée avec Oracle JDK mais pas JRE!
Vous ne pouvez pas obtenir tool.jardu repo Maven; le configurer avec Maven est un peu délicat
Le tool.jarcontient probablement du code dépendant de la plate-forme (natif?) Donc il n'est pas facilement distribuable
Il fonctionne en supposant que toutes les applications JVM (locales) en cours d'exécution sont "contrôlables". Il semble que depuis Java 6, toutes les applications le sont généralement (sauf si vous configurez activement ci-contre)
Cela ne fonctionne probablement que pour Java 6+
Eclipse ne publie pas de classe principale, donc vous n'obtiendrez pas facilement Eclipse PID. Bug dans MonitoredVmUtil?
MISE À JOUR: Je viens de vérifier que JPS utilise de cette façon, c'est-à-dire la bibliothèque Jvmstat (qui fait partie de tool.jar). Il n'est donc pas nécessaire d'appeler JPS en tant que processus externe, appelez directement la bibliothèque Jvmstat comme mon exemple le montre. Vous pouvez également obtenir la liste de toutes les JVM qui s'exécutent sur localhost de cette façon. Voir le code source JPS :
Sur la base de la réponse d' Ashwin Jayaprakash (+1) à propos de la licence Apache 2.0 SIGAR, voici comment je l'utilise pour obtenir uniquement le PID du processus actuel:
Je sais que c'est un vieux fil, mais je voulais appeler cette API pour obtenir le PID (ainsi que d'autres manipulations du processus Java au moment de l'exécution) est ajoutée à la classe Process dans JDK 9: http: // openjdk. java.net/jeps/102
Wow, c'était rapide. Cela n'a pris que sept ans environ! 😃
Dmitry Shechtman
1
J'ai trouvé une solution qui peut être un peu un cas de bord et je ne l'ai pas essayée sur un autre système d'exploitation que Windows 10, mais je pense qu'il vaut la peine de le remarquer.
Si vous vous retrouvez à travailler avec J2V8 et nodejs, vous pouvez exécuter une simple fonction javascript vous renvoyant le pid du processus java.
Cela ne vérifie pas si pid est en cours d'utilisation, mais si pid est égal au processus actuel pid
c0der
Quelle est la bonne solution pour pouvoir mettre à jour mon code?
PartialData
-6
C'est ce que j'ai utilisé lorsque j'avais des exigences similaires. Cela détermine correctement le PID du processus Java. Laissez votre code java générer un serveur sur un numéro de port prédéfini, puis exécutez les commandes du système d'exploitation pour découvrir l'écoute PID sur le port. Pour Linux
Réponses:
Il n'existe aucun moyen indépendant de la plateforme qui puisse être garanti de fonctionner dans toutes les implémentations jvm.
ManagementFactory.getRuntimeMXBean().getName()
ressemble à la meilleure solution (la plus proche). Il est court et fonctionne probablement dans toutes les implémentations largement utilisées.Sur linux + windows, il retourne une valeur comme
12345@hostname
(12345
étant l'identifiant du processus). Attention cependant selon les documents , il n'y a aucune garantie sur cette valeur:Dans Java 9, la nouvelle API de processus peut être utilisée:
la source
Vous pouvez utiliser JNA . Malheureusement, il n'y a pas encore d'API JNA commune pour obtenir l'ID de processus actuel, mais chaque plate-forme est assez simple:
les fenêtres
Assurez-vous d'avoir
jna-platform.jar
alors:Unix
Déclarer:
Ensuite:
Java 9
Sous Java 9, la nouvelle API de processus peut être utilisée pour obtenir l'ID de processus actuel. Commencez par saisir un descripteur du processus en cours, puis interrogez le PID:
la source
getpid()
solution fonctionne également pour OS X, avec un appel JNA à la bibliothèque "System".error: cannot find symbol
pour jdk9Voici une méthode de porte dérobée qui pourrait ne pas fonctionner avec toutes les machines virtuelles mais devrait fonctionner à la fois sur Linux et Windows ( exemple original ici ):
la source
getDeclaredMethod
sur l'objet retourné parjvm.get(runtime)
.Essayez Sigar . API très étendues. Licence Apache 2.
la source
La méthode suivante tente d'extraire le PID de
java.lang.management.ManagementFactory
:Appelez
getProcessId("<PID>")
, par exemple.la source
Pour les anciennes JVM, sous Linux ...
la source
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
. Pourquoi les girations supplémentaires?getCanonicalFile()
méthode qui convertit le «moi» en PID?Vous pouvez consulter mon projet: JavaSysMon sur GitHub. Il fournit un identifiant de processus et un tas d'autres choses (utilisation du processeur, utilisation de la mémoire) multiplateforme (actuellement Windows, Mac OSX, Linux et Solaris)
la source
Depuis Java 9, il existe une méthode Process.getPid () qui renvoie l'ID natif d'un processus:
Pour obtenir l'ID de processus du processus Java actuel, on peut utiliser l'
ProcessHandle
interface:la source
À Scala:
Cela devrait vous fournir une solution de contournement sur les systèmes Unix jusqu'à la sortie de Java 9. (Je sais, la question concernait Java, mais comme il n'y a pas de question équivalente pour Scala, je voulais laisser cela aux utilisateurs de Scala qui pourraient tomber sur la même question.)
la source
Pour être complet, il y a un wrapper dans Spring Boot pour le
Solution. Si un entier est requis, cela peut se résumer à la ligne unique:
Si quelqu'un utilise déjà Spring boot, il / elle peut utiliser org.springframework.boot.ApplicationPid
La méthode toString () imprime le pid ou '???'.
Les mises en garde à l'aide de ManagementFactory sont déjà discutées dans d'autres réponses.
la source
la source
la source
Le dernier que j'ai trouvé est qu'il existe une propriété système appelée
sun.java.launcher.pid
qui est disponible au moins sur Linux. Mon plan est de l'utiliser et s'il n'est pas trouvé d'utiliser leJMX bean
.la source
Cela dépend d'où vous cherchez les informations.
Si vous recherchez les informations de la console, vous pouvez utiliser la commande jps. La commande donne une sortie similaire à la commande Unix ps et est livrée avec le JDK car je crois que 1.5
Si vous cherchez à partir du processus, le RuntimeMXBean (comme l'a dit Wouter Coekaerts) est probablement votre meilleur choix. La sortie de getName () sous Windows à l'aide de Sun JDK 1.6 u7 se présente sous la forme [PROCESS_ID] @ [MACHINE_NAME]. Vous pouvez cependant essayer d'exécuter jps et d'analyser le résultat à partir de cela:
S'il est exécuté sans options, la sortie doit être l'ID du processus suivi du nom.
la source
Il s'agit du code JConsole et potentiellement utilisé par jps et VisualVM. Il utilise des classes de
sun.jvmstat.monitor.*
package, detool.jar
.Il y a peu de captures:
tool.jar
est une bibliothèque distribuée avec Oracle JDK mais pas JRE!tool.jar
du repo Maven; le configurer avec Maven est un peu délicattool.jar
contient probablement du code dépendant de la plate-forme (natif?) Donc il n'est pas facilement distribuableMISE À JOUR: Je viens de vérifier que JPS utilise de cette façon, c'est-à-dire la bibliothèque Jvmstat (qui fait partie de tool.jar). Il n'est donc pas nécessaire d'appeler JPS en tant que processus externe, appelez directement la bibliothèque Jvmstat comme mon exemple le montre. Vous pouvez également obtenir la liste de toutes les JVM qui s'exécutent sur localhost de cette façon. Voir le code source JPS :
la source
J'ajoute cela, à d'autres solutions.
avec Java 10, pour obtenir
process id
la source
Sur la base de la réponse d' Ashwin Jayaprakash (+1) à propos de la licence Apache 2.0
SIGAR
, voici comment je l'utilise pour obtenir uniquement le PID du processus actuel:Même s'il ne fonctionne pas sur toutes les plates-formes, il fonctionne sur Linux, Windows, OS X et diverses plates-formes Unix comme indiqué ici .
la source
Vous pouvez essayer
getpid()
dans JNR-Posix .Il a un wrapper Windows POSIX qui appelle getpid () hors de libc.
la source
Je sais que c'est un vieux fil, mais je voulais appeler cette API pour obtenir le PID (ainsi que d'autres manipulations du processus Java au moment de l'exécution) est ajoutée à la classe Process dans JDK 9: http: // openjdk. java.net/jeps/102
la source
J'ai trouvé une solution qui peut être un peu un cas de bord et je ne l'ai pas essayée sur un autre système d'exploitation que Windows 10, mais je pense qu'il vaut la peine de le remarquer.
Si vous vous retrouvez à travailler avec J2V8 et nodejs, vous pouvez exécuter une simple fonction javascript vous renvoyant le pid du processus java.
Voici un exemple:
la source
Voici ma solution:
la source
C'est ce que j'ai utilisé lorsque j'avais des exigences similaires. Cela détermine correctement le PID du processus Java. Laissez votre code java générer un serveur sur un numéro de port prédéfini, puis exécutez les commandes du système d'exploitation pour découvrir l'écoute PID sur le port. Pour Linux
la source
bash -c 'echo $PPID'
ou les réponses