Создание графика визуальных вызовов для Java-проектов из командной строки
Я хочу создать callgraph для java-проектов из командной строки. Я изучил несколько проектов, каждый раз не поддающийся (как в моем понимании, так и в функциональности) того, к чему я стремлюсь. Некоторые простые рекомендации о том, как это сделать, были бы замечательными, дополнительная цель - получить текстовое представление этого графика.
Вот что я пробовал:
Call-graph: https://github.com/gousiosg/java-callgraph
Это дает мне текстовый вывод, который я хочу, но я не могу найти способ (после просмотра документации в течение некоторого времени), чтобы превратить это в графический вывод визуального (графического файла).
Сажа: http://sable.github.io/soot/
Проведя огромное количество времени, просматривая документацию SOOT, которая кажется довольно сложной, мне удалось заставить SOOT создать байт-код. Тем не менее, я не могу найти никаких руководств о том, как создать граф вызовов из него. Я только вижу на главной странице, что он может это сделать, и я получаю несколько сообщений по электронной почте из моих поисковых запросов Google, все, что является просто вопросами без ответов. Я использую ночную сборку с командой:
java -cp soot-trunk.jar soot.Main -cp . -pp HelloWorld
Где HelloWorld - это имя моего java файла, я получаю вывод, который является файлом .class, но я не вижу, как получить фактический график вызовов. Ниже приведено руководство: https://github.com/Sable/soot/wiki/Running-Soot. Когда я следую ссылкам о визуализации, они, похоже, являются неработающими ссылками, которые затем перенаправляются на главную страницу. Я могу увидеть некоторую информацию об использовании флага -cg на странице командной строки, но не могу заставить ничего работать - я просто получаю ошибку синтаксического анализа, предлагая недопустимый аргумент: https://ssebuild.cased.de/nightly/soot/doc/soot_options.htm#phase_5
Поиск stackoverflow - существующие ответы
Я уже рассмотрел несколько похожих вопросов, таких как: Статический анализ графика вызовов Java
Тем не менее, ответы просто говорят "использовать сажу" или "использовать call-graph", я пробовал их без везения - хотя я ближе всего к графу вызовов, так как у меня есть текстовый вывод.
Я вижу некоторые плагины на основе графического интерфейса и плагины eclipse, которые утверждают, что создают диаграммы вызовов, но я пытаюсь заставить это работать из командной строки.
Любая помощь действительно оценена, руководство или набор команд с помощью call-graph или Soot, или другая программа действительно поможет. Возможно, стоит также передать какой-либо короткий учебник им для их документации, поскольку, кажется, задавайте больше вопросов, чем ответов при поиске.
Для справки, в настоящее время я пытаюсь выполнить очень простой класс:
public class HelloWorld {
public static void main(String[] args) {
foo();
}
public static void foo(){
System.out.println("Hello World");
}
}
Ответы
Ответ 1
Это похоже на то, что Call Graph производит довольно приличный вывод. Позвольте сделать быстрый PoC.
Я использую образец вывода, предоставляемый разработчиком Call Graph.
org.apache.batik.dom.AbstractParentNode:appendChild org.apache.batik.dom.AbstractParentNode:fireDOMNodeInsertedEvent 6270
org.apache.batik.dom.AbstractParentNode:fireDOMNodeInsertedEvent org.apache.batik.dom.AbstractDocument:getEventsEnabled 6280
org.apache.batik.dom.AbstractParentNode:checkAndRemove org.apache.batik.dom.AbstractNode:getOwnerDocument 6280
org.apache.batik.dom.util.DoublyIndexedTable:put org.apache.batik.dom.util.DoublyIndexedTable$Entry:DoublyIndexedTable$Entry 6682
org.apache.batik.dom.util.DoublyIndexedTable:put org.apache.batik.dom.util.DoublyIndexedTable:hashCode 6693
org.apache.batik.dom.AbstractElement:invalidateElementsByTagName org.apache.batik.dom.AbstractElement:getNodeType 7198
org.apache.batik.dom.AbstractElement:invalidateElementsByTagName org.apache.batik.dom.AbstractDocument:getElementsByTagName 14396
org.apache.batik.dom.AbstractElement:invalidateElementsByTagName org.apache.batik.dom.AbstractDocument:getElementsByTagNameNS 28792
Есть несколько доступных графических движков. Самое простое - DOT
(пожалуйста, проверьте ссылку, есть еще несколько других полезных инструментов).
Чтобы использовать DOT
, мне нужно немного преобразовать данные. Скажем, я хотел бы сохранить ClassName: methodName и пропустить пакет.
Это очень просто, вы можете использовать любой инструмент для этого, но я буду использовать sed
:
OUT=callgraph.dot
echo "graph test {" > $OUT
sed -E 's/[a-z]+\.//g; s/[0-9]+\/;/; s/ / -- /; s/[\$|\:]/_/g' callgraph.txt >> $OUT
echo "}" >> $OUT
dot -Tpng callgraph.dot -o callgraph.png
Вот результат:
graph test {
AbstractParentNode_appendChild -- AbstractParentNode_fireDOMNodeInsertedEvent ;
AbstractParentNode_fireDOMNodeInsertedEvent -- AbstractDocument_getEventsEnabled ;
AbstractParentNode_checkAndRemove -- AbstractNode_getOwnerDocument ;
DoublyIndexedTable_put -- DoublyIndexedTable_Entry_DoublyIndexedTable_Entry ;
DoublyIndexedTable_put -- DoublyIndexedTable_hashCode ;
AbstractElement_invalidateElementsByTagName -- AbstractElement_getNodeType ;
AbstractElement_invalidateElementsByTagName -- AbstractDocument_getElementsByTagName ;
AbstractElement_invalidateElementsByTagName -- AbstractDocument_getElementsByTagNameNS ;
}
DOT
было довольно красиво сделать это следующим:
![enter image description here]()
Все графики были извлечены из исходных данных:
![enter image description here]()
Обратите внимание, что вы можете настроить рендеринг по своему усмотрению. DOT
является частью graphviz, который представляет собой довольно гибкий набор инструментов.
За моим ответом есть общая идея:
- используйте любой подходящий инструмент для создания трассировки
- найти хорошее решение для рендеринга
- потратить некоторое время, чтобы получить простое автоматическое преобразование
BTW, посмотрите canviz
Canviz - это библиотека JavaScript для рисования графиков Graphviz в Интернете холст браузера. Более технически, Canviz - это JavaScript xdot визуализатор. Он работает в большинстве современных браузеров.
Счастливое кодирование:)
Ответ 2
Там также WALA: http://wala.sourceforge.net/wiki/index.php/Main_Page
Он поддерживает несколько стратегий построения диаграмм вызовов и уже имеет интеграцию с DOT. Если вы следуете руководству по началу работы, они уже содержат ряд примеров программ, которые визуально отображают график вызовов. Их список пользователей также весьма полезен.
Здесь упоминается пример, который отображает график вызовов:
http://wala.sourceforge.net/wiki/index.php/UserGuide:Getting_Started#Other_basic_examples