从命令行为 java 个项目创建可视调用图
Creating a visual call graph for java projects from command line
我正在寻找从命令行为 java 项目创建一个调用图。我探索了几个项目,每次都达不到我的目标(无论是在我的理解上,还是在功能上)。关于如何执行此操作的一些简单指南会很棒,另一个目标是获得此图的文本表示。
这是我试过的:
调用图: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. When I follow links about visualisations, they seem to be broken links which then redirect back to the homepage. I can see some information about using the -cg flag on the command line page, but can't get anything to work - I just get an option parse error, suggesting an invalid argument: https://ssebuild.cased.de/nightly/soot/doc/soot_options.htm#phase_5
正在搜索 Whosebug - 现有答案
我已经看过几个类似的问题,例如:Static analysis of Java call graph
然而,答案只是说 "use soot",或 "use call-graph",我一直在尝试这些但没有任何运气 - 尽管我最接近调用图,因为我有文本输出。
我看到一些声称可以创建调用图的基于 GUI 的软件和 eclipse 插件,但我正试图从命令行让它工作。
非常感谢任何帮助,一个指南,或者一组带有调用图或 Soot 的命令,或者另一个程序 help.It 也可能值得将任何简短教程提交给他们以获取他们的文档因为搜索的时候问题好像比答案多。
作为参考,我目前正在尝试使用以下非常简单的 class:
public class HelloWorld {
public static void main(String[] args) {
foo();
}
public static void foo(){
System.out.println("Hello World");
}
}
看起来 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
(请检查 link,列出了其他几个好工具)。
为了使用 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
非常友好地将其呈现为以下内容:
所有图表都是从初始数据中提取的:
请注意,您可以根据需要调整渲染。 DOT
是 graphviz 的一部分,后者是一套非常灵活的工具。
我的回答背后有一个大概的思路:
- 使用任何合适的工具生成跟踪
- 找一个好的渲染方案
- 花一些时间以获得简单的自动转换
顺便说一句,看看canviz
Canviz is a JavaScript library for drawing Graphviz graphs to a web
browser canvas. More technically, Canviz is a JavaScript xdot
renderer. It works in most modern browsers.
编码愉快:)
还有 WALA:http://wala.sourceforge.net/wiki/index.php/Main_Page
它支持多种调用图构建策略,并且已经与 DOT 集成。如果您遵循入门指南,它们已经包含许多示例程序,可以直观地显示调用图。他们的用户列表也很支持
这里他们提到了一个显示调用图的例子:
http://wala.sourceforge.net/wiki/index.php/UserGuide:Getting_Started#Other_basic_examples
这是一个老问题,但我仍然没有找到好的工具。因此,根据关于此线程的建议,我创建了 java-call-graph-plotter。它使用 java-call-graph 和 VisJs 来做到这一点。
您可以按照以下步骤操作:
克隆 repo 并进入项目文件夹:
git clone https://github.com/marcello-dev/java-call-graph-plotter.git
cd java-call-graph-plotter
创建调用图:
java -jar javacg/javacg-0.1-SNAPSHOT-static.jar target-jar/demo-customer-0.0.1-SNAPSHOT.jar > call-graph.txt
为 Python 3 创建一个虚拟环境:
python3 -m venv venv
激活它:
source venv/bin/activate
安装依赖项:
pip install -r requirements.txt
绘制图形:
python callgraphplotter.py call-graph.txt ApiDBSelector
将在输出文件夹中生成一个名为 call-graph.html 的文件。您可以在浏览器中打开它。希望对你有帮助!更多信息 here
我正在寻找从命令行为 java 项目创建一个调用图。我探索了几个项目,每次都达不到我的目标(无论是在我的理解上,还是在功能上)。关于如何执行此操作的一些简单指南会很棒,另一个目标是获得此图的文本表示。
这是我试过的:
调用图: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. When I follow links about visualisations, they seem to be broken links which then redirect back to the homepage. I can see some information about using the -cg flag on the command line page, but can't get anything to work - I just get an option parse error, suggesting an invalid argument: https://ssebuild.cased.de/nightly/soot/doc/soot_options.htm#phase_5
正在搜索 Whosebug - 现有答案 我已经看过几个类似的问题,例如:Static analysis of Java call graph 然而,答案只是说 "use soot",或 "use call-graph",我一直在尝试这些但没有任何运气 - 尽管我最接近调用图,因为我有文本输出。
我看到一些声称可以创建调用图的基于 GUI 的软件和 eclipse 插件,但我正试图从命令行让它工作。
非常感谢任何帮助,一个指南,或者一组带有调用图或 Soot 的命令,或者另一个程序 help.It 也可能值得将任何简短教程提交给他们以获取他们的文档因为搜索的时候问题好像比答案多。
作为参考,我目前正在尝试使用以下非常简单的 class:
public class HelloWorld {
public static void main(String[] args) {
foo();
}
public static void foo(){
System.out.println("Hello World");
}
}
看起来 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
(请检查 link,列出了其他几个好工具)。
为了使用 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
非常友好地将其呈现为以下内容:
所有图表都是从初始数据中提取的:
请注意,您可以根据需要调整渲染。 DOT
是 graphviz 的一部分,后者是一套非常灵活的工具。
我的回答背后有一个大概的思路:
- 使用任何合适的工具生成跟踪
- 找一个好的渲染方案
- 花一些时间以获得简单的自动转换
顺便说一句,看看canviz
Canviz is a JavaScript library for drawing Graphviz graphs to a web browser canvas. More technically, Canviz is a JavaScript xdot renderer. It works in most modern browsers.
编码愉快:)
还有 WALA:http://wala.sourceforge.net/wiki/index.php/Main_Page
它支持多种调用图构建策略,并且已经与 DOT 集成。如果您遵循入门指南,它们已经包含许多示例程序,可以直观地显示调用图。他们的用户列表也很支持
这里他们提到了一个显示调用图的例子:
http://wala.sourceforge.net/wiki/index.php/UserGuide:Getting_Started#Other_basic_examples
这是一个老问题,但我仍然没有找到好的工具。因此,根据关于此线程的建议,我创建了 java-call-graph-plotter。它使用 java-call-graph 和 VisJs 来做到这一点。 您可以按照以下步骤操作:
克隆 repo 并进入项目文件夹:
git clone https://github.com/marcello-dev/java-call-graph-plotter.git
cd java-call-graph-plotter
创建调用图:
java -jar javacg/javacg-0.1-SNAPSHOT-static.jar target-jar/demo-customer-0.0.1-SNAPSHOT.jar > call-graph.txt
为 Python 3 创建一个虚拟环境:
python3 -m venv venv
激活它:
source venv/bin/activate
安装依赖项:
pip install -r requirements.txt
绘制图形:
python callgraphplotter.py call-graph.txt ApiDBSelector
将在输出文件夹中生成一个名为 call-graph.html 的文件。您可以在浏览器中打开它。希望对你有帮助!更多信息 here