Как проверить, загружен класс или нет в процессе Java - PullRequest
1 голос
/ 17 апреля 2019

Моя задача - узнать, сколько приложений Springboot работает в системе Linux. Итак, что я планирую сделать, это

1. для получения всех идентификаторов процесса Java

$ ps -aux|grep java

2. Затем каким-то образом получить загруженные классы из идентификаторов.

Я не знаю, возможно ли это или нет. Кто-то, пожалуйста, достаточно любезен, чтобы направить меня в правильном направлении? P.S. : Я использую Java для запуска вышеуказанной команды с помощью класса Process, что-то вроде этого:

Process process = Runtime.getRuntime().exec("ps -ef");

Так что я хочу сделать это из Java-проекта.

Ответы [ 3 ]

0 голосов
/ 17 апреля 2019

Быстрый и грязный метод: какой-то статический блок в ваш класс и в нем что-то выводится в журнал (или system.out).Статический блок выполняется, когда класс загружается загрузчиком классов, а не когда создается первый экземпляр (это когда конструктор вызывается в первый раз).Затем, если ваша распечатка находится в журнале, класс загружен.Пример:
public class Sample { private static final Logger logger = ... static { logger.info("class Sample is loaded"); } ... }

0 голосов
/ 17 апреля 2019

Предполагая, что вы можете определить какой-то конкретный класс, который определяет, является ли приложение приложением Springboot, вы можете использовать какой-то инструмент из jdk, который может выводить загруженные классы.Я пробовал это с jcmd (вы найдете это в jre / bin /):

Я не очень хорош в bash, поэтому он может быть не очень эффективным, но это работает для меня, если предположить, что каждыйПриложение Springboot загрузило класс org.springframework.boot.logging.LoggingInitializationContext, и никакое приложение, не являющееся Springboot, загрузило его.

ps aux | grep [j]ava | awk '{print $2}' | xargs -I{} jcmd {} VM.class_hierarchy | grep "org.springframework.boot.logging.LoggingInitializationContext"

Он находит процессы, содержащие java, получает только PID, передает его в jcmd, где вы grep для определенного класса.Вывод кажется правильным, единственная проблема в том, что я потерял PID в этой длинной трубе, и я не уверен, как его распечатать.Но если ваша проблема в том, «сколько приложений Springboot», то это не проблема.Я также не уверен, что классы могут появляться дважды при использовании jcmd VM.class_hierarchy, но это не похоже на это.

Примечание: это работает на JDK 11. Сначала я попробовал jmap, но по некоторым причинам это не работает для меня на JDK 11.

0 голосов
/ 17 апреля 2019
  1. Вам необходимо добавить какой-то идентификатор в командную строку запуска вашего приложения. Например. что-то вроде:

    String id = "com.app.demo";
    
  2. Когда вы запускаете свое приложение, обязательно включайте строку. Допустим, вы запускаете его из Java, сделайте следующее:

    Runtime.getRuntime().exec("C:\...\javaw.exe -cp ... -Dwhatever=" + id + " com.app.app.demo.Main");
    
  3. Получить заявку можно по id, как $ps aux | grep -i com.app.app.demo. В Java звоните Runtime.getRuntime().exec("ps aux | grep -i com.app.app.demo");

Я бы предпочел вместо этого использовать ProcessBuilder (из Java 8) и выполнить команду через bash:

Process process = new ProcessBuilder().command("bash", "ps aux | grep com.app.app.demo").start()

Надеюсь, что это дает представление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...