Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Отладка Java приложения, когда оно вовсе не ждёт — благо пожаловать в InTrace подход

Anna | 1.06.2014 | нет комментариев

Доводилось ли вам когда-либо изучать шаг за шагом выполние некого Java кода, тот, что не удосужились снабдить средствами логирования либо прочими механизмами слежения?
Усложним задачу тем, что не будем перекомпилировать изучаемый код, да и вообще перезапускать присутствующий процесс (тот случай, когда непонятное поведение было да и при перестарте сплыло). Java машина, безусловно же, запущена с самыми обычными опциями (без параметров для аттача дебагера либо ещё каких наворотов).
А так хочется осознать, что же происходит.

Именно этим мы и займёмся.

Для наглядного примера возьмём примитивный код, некоторое подобие реализации ветхой добродушной каждому знаменитой сказки «Репка». Цель демонстрации ниже приведённого кода совсем не показать красоту организации классов либо способов, а тем больше нейминга (здесь, скорее, бесчинство), а легко сделать ряд вызовов за вызовом.

     1: package skazka; 
     2: 
     3: import java.io.BufferedReader; 
     4: import java.io.InputStreamReader; 
     5: 
     6: public class Repka { 
     7:   public static void main(String[] args) throws Exception { 
     8:     new BufferedReader(new InputStreamReader(System.in)).readLine(); 
     9: 
    10:     try { 
    11:       new Dedka().tyanem("репка", 200); 
    12:     } catch (Exception ex) { 
    13:       processError(ex); 
    14:     } 
    15:     
    16:   } 
    17: 
    18:   public static boolean processError(Exception ex) { 
    19:     // ... 
    20:     return true; 
    21:   } 
    22: } 
    23: 
    24: class Dedka { 
    25:   void tyanem(String target, int weight) { 
    26:     new Babka().tyanem(target, weight - 15); 
    27:   } 
    28: } 
    29: 
    30: class Babka { 
    31:   void tyanem(String target, int weight) { 
    32:     new Vorona().tyanem(target, weight - 10); 
    33:   } 
    34: } 
    35: 
    36: class Vorona { 
    37:   void tyanem(String target, int weight) { 
    38:     if (!target.equals("сыр")) { 
    39:       throw new RuntimeException("Ворона ждёт от всевышнего сыра"); 
    40:     } 
    41: 
    42:     // ... 
    43:   } 
    44: } 
    

Скомпилируем

javac skazka/Repka.java

И запустим

java skazka.Repka

Сейчас нужно как-то «вклиниться» в теснее запущенный процесс и адаптировать код под свои нужды. Для этого изумительно подходит Java-шпион сделанный Мартином Робертсоном (за что ему много-много искренней благодарности), под наименованием InTrace mchr3k.github.io/org.intrace, разрешающий на лету внедряться в исполняемый код, снабжая его элементами трейсинга.

InTrace шпион помещается в теснее запущенный Java процесс парой примитивных методов (на выбор):
1) программным способом

public static void loadAgent(String pid, String agentFilePath) throws Exception {
    VirtualMachine vm = VirtualMachine.attach(pid);
    vm.loadAgent(agentFilePath, "");
    vm.detach();
}

Подсунув процессу джава-шпион intrace-agent.jar изgithub.com/mchr3k/org.intrace/tree/master/binaries/jars/latest_development

2) взяв VisualVM (скачав, если нет отсель visualvm.java.net) и пропатчив его (Tools->Plugins) InTrace плагином org-intrace-visualvm.nbm взятым из
github.com/mchr3k/org.intrace/tree/master/binaries/jars/latest_development

Напасть в том, что в org-intrace-visualvm.nbm не самые свежие файлы, следственно обнаружьте где VisualVM хранит плагины и подмените соответствующие джарники на больше свежие изgithub.com/mchr3k/org.intrace/tree/master/binaries/jars/latest_development
В моём случае (ОС Linux), следовало подменить
intrace-agent.jar на intrace-agent.jar и intrace-client-gui-linux.jar на intrace-ui.jar (см. скриншот ниже, плагин подсказывает пути)

Сейчас остаётся запустить VisualVM, вызвать для skazka.Repka контекстное меню и предпочесть «InTrace Application…», позже чего увидим

жмём кнопку «Load InTrace Agent» и консоль доложит о внедрении InTrace текстом на подобие

Стадия внедрения удачно закончена: в Java машине удачно поселился InTrace шпион, готовый трансформировать байт код, снабжая его командами трейса, и извещать итоги.

Переходим к стадии слежения за итогом, для чего запускаем инструмент управления агентом и обзора итогов (отдельное приложение).

Вновь существует два примитивных варианта
1) мы внедряли шпион первым «программным методом» тогда запускаем

java -jar intrace-ui.jar  

взятым здесь
github.com/mchr3k/org.intrace/tree/master/binaries/jars/latest_development
2) в случае применения VisualVM, нажимаем кнопку «Launch InTrace Client», и, в тезисе, запустится безусловно тот же файл, что и в первом примере (от того что мы впатчили новейший intrace-ui.jar)

Вбиваем адрес, настраиваем параметры трейса (я включил Entry/Exit Branch Args), жмём кнопку «Classes…» и указываем там skazka (это принудит добавить трейсинг в классы из пакета skazka).
Нажимаем «Enter» в консоли c запущенной «Репкой» (не забываем что именно этого она и ждёт для продолжения) и в конце концов получим на заказчике цепочку исполнения программы в виде итога:

[21:52:39.861]:[1]:skazka.Dedka:<init>: {:24
[21:52:39.862]:[1]:skazka.Dedka:<init>: }:24
[21:52:39.862]:[1]:skazka.Dedka:tyanem: {:26
[21:52:39.865]:[1]:skazka.Dedka:tyanem: Arg (target): репка
[21:52:39.866]:[1]:skazka.Dedka:tyanem: Arg (weight): 200
[21:52:39.868]:[1]:skazka.Babka:<init>: {:30
[21:52:39.869]:[1]:skazka.Babka:<init>: }:30
[21:52:39.871]:[1]:skazka.Babka:tyanem: {:32
[21:52:39.871]:[1]:skazka.Babka:tyanem: Arg (target): репка
[21:52:39.871]:[1]:skazka.Babka:tyanem: Arg (weight): 185
[21:52:39.878]:[1]:skazka.Vorona:<init>: {:36
[21:52:39.878]:[1]:skazka.Vorona:<init>: }:36
[21:52:39.878]:[1]:skazka.Vorona:tyanem: {:38
[21:52:39.879]:[1]:skazka.Vorona:tyanem: Arg (target): репка
[21:52:39.879]:[1]:skazka.Vorona:tyanem: Arg (weight): 175
[21:52:39.879]:[1]:skazka.Vorona:tyanem: /:39
[21:52:39.885]:[1]:skazka.Vorona:tyanem: Throw:39: java.lang.RuntimeException: Ворона ждёт от всевышнего сыра
	at skazka.Vorona.tyanem(Repka.java:39)
	at skazka.Babka.tyanem(Repka.java:32)
	at skazka.Dedka.tyanem(Repka.java:26)
	at skazka.Repka.main(Repka.java:11)

[21:52:39.885]:[1]:skazka.Vorona:tyanem: }:39
[21:52:39.886]:[1]:skazka.Repka:main: /:13
[21:52:39.890]:[1]:skazka.Repka:processError: {:20
[21:52:39.890]:[1]:skazka.Repka:processError: Arg (ex): java.lang.RuntimeException: Ворона ждёт от всевышнего сыра
[21:52:39.891]:[1]:skazka.Repka:processError: Return: 1
[21:52:39.891]:[1]:skazka.Repka:processError: }:20
[21:52:39.891]:[1]:skazka.Repka:main: }:16

Всякая строка итога описывается дальнейшим форматом

[текущее время]:[идентификатор потока]:пакет:способ:добавочная информация

где:
нынешнее время — говорит само за себя
идентификатор потока — неповторимый идентификатор потока, различные потоки — различные числа (1, 2, 3, 4, …)
пакет — пространство имён
способ — имя способа, в котором происходит выполнение
добавочная информация — зависит от обстановки

Поддерживаемые виды трейса:
— входвыход способа

[21:52:39.861]:[1]:skazka.Dedka:<init>: {:24
[21:52:39.862]:[1]:skazka.Dedka:<init>: }:24

либо

[21:52:39.890]:[1]:skazka.Repka:processError: {:20

— ветвления

[21:52:39.879]:[1]:skazka.Vorona:tyanem: /:39

— доводы (отображение объектов идёт через toString() )

[21:52:39.865]:[1]:skazka.Dedka:tyanem: Arg (target): репка
[21:52:39.866]:[1]:skazka.Dedka:tyanem: Arg (weight): 200

-возвращаемые значения

[21:38:31.444]:[1]:skazka.Repka:processError: Return: 1

— исключения

[21:52:39.885]:[1]:skazka.Vorona:tyanem: Throw:39: java.lang.RuntimeException: Ворона ждёт от всевышнего сыра
	at skazka.Vorona.tyanem(Repka.java:39)
	at skazka.Babka.tyanem(Repka.java:32)
	at skazka.Dedka.tyanem(Repka.java:26)
	at skazka.Repka.main(Repka.java:11)

В целом — всё что нужно для удачного понимания хода выполнения программы.

Потренируйтесь исследовать итог на вышеприведённом примере (кое-что может быть сходу подсознательно не вовсе ясно, но разобравшись стремительно привыкаешь).

С наглядным примером, во что превращается код (как расставляются трейсы) дозволено ознакомиться на странице автора mchr3k.github.io/org.intrace/howintraceworks.html

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB