Создание графика визуальных вызовов для 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