Java调用图的静态分析

时间:2011-02-09 22:50:51

标签: java static analysis call-graph

我想要做的是扫描一组Java类,并从抽象类的特定方法跟踪所有方法调用,并在该上下文中,构建执行某些操作的所有代码的列表(在此case,实例化某个类的实例)。我想知道,行号和提供的参数。

我已经开始关注BCEL,但它似乎没有内置调用图形跟踪?我很想写自己的,因为获得重载,类型签名和多态调度权利可能会很棘手。

我有一半期望存在一个工具或示例代码,但我还没有找到任何东西。我真的觉得我要重新发明一个轮子。但是,如果我这样做将是一个开源轮,可以在GitHub上使用; - )

PS:你会发现现有的问题“How to Generator a Java Call Graph”,因为它听起来很相似,但它根本不是我需要的。

7 个答案:

答案 0 :(得分:5)

您可以尝试JavaDepend,它提供了依赖项和指标所需的许多功能,它还提供了一个类似SQL的CQL来请求您的代码库。

答案 1 :(得分:5)

您可以使用java-callgraph工具套件为Java创建足够准确的静态和动态调用图。

答案 2 :(得分:4)

您可以将DoxygenGraphviz一起使用。它易于安装和使用。

答案 3 :(得分:3)

烟灰应该可以让您轻松实现您的目标: http://www.sable.mcgill.ca/soot/

它可以完全自动构建精确的调用图。

您可以在此处找到所有必要的文档: http://www.sable.mcgill.ca/soot/tutorial/index.html

此外,还有一个活跃的Soot邮件列表。

答案 4 :(得分:2)

听起来你想要一些可以访问抽象语法和完整符号表的东西。然后,根据抽象方法的每个实现方法(如符号表所示)对调用图中函数的AST进行自定义扫描,使您有机会找到类型为特定感兴趣类的新操作。 / p>

DMS Software Reengineering Toolkit是通用编译器技术,提供解析,AST构建/导航,符号表构建/导航,控制流,数据流和调用图构造等基本服务。 DMS具有可选的Java Front End,它提供完整的Java解析器,构建Java AST和符号表,并且可以构建调用图。 Java前端还可以读取.class文件;你不清楚你是否想要爬进课堂档案,寻找信息。

你想要的答案不是现成的。您需要构建一些自定义代码来实现第一段中的想法,但DMS可以提供​​大部分原材料。它没有从.class文件中提供太多细节(这些文件主要用于解析源代码中的类型)。

答案 5 :(得分:0)

有关最近的Eclipse安装(相对于该问题),请参见Certiv CallGraph

CallGraph可以对程序调用关系和流程排序进行图形分析。还可以探索扩展的类继承层次结构。

调用路径分析和类层次结构解析是使用JDT平台的搜索和调用层次结构机制执行的。

序列图是通过对任何选定的类或方法的JDT平台AST的静态分析生成的。

使用Zest作为图形可视化引擎。

您可以通过 Eclipse市场安装它。我没有参与这项工作。 您不能缩小视图,但不是很实用,但是它支持顺序图,这很好,并且可以按需打开/关闭节点以进一步挖掘。

要求:

Eclipse 4.6 (Neon) on Java 8 VM
Eclipse Zest Visualization Toolkit 1.7

Eclipse Public License v1.0

答案 6 :(得分:0)

你可以看到: https://github.com/Adrninistrator/java-all-call-graph/blob/main/README-en.md

输出示例:

  • 向上
org.mybatis.spring.SqlSessionUtils:lambda$closeSqlSession$6(org.apache.ibatis.session.SqlSession)
[0]#org.mybatis.spring.SqlSessionUtils:lambda$closeSqlSession$6(org.apache.ibatis.session.SqlSession)
[1]#  org.mybatis.spring.SqlSessionUtils:closeSqlSession(org.apache.ibatis.session.SqlSession,org.apache.ibatis.session.SqlSessionFactory)
[2]#    org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor:invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object[])    !entry!

org.mybatis.spring.SqlSessionUtils:lambda$getSqlSession$0()
[0]#org.mybatis.spring.SqlSessionUtils:lambda$getSqlSession$0()
[1]#  org.mybatis.spring.SqlSessionUtils:getSqlSession(org.apache.ibatis.session.SqlSessionFactory) !entry!
[1]#  org.mybatis.spring.SqlSessionUtils:getSqlSession(org.apache.ibatis.session.SqlSessionFactory,org.apache.ibatis.session.ExecutorType,org.springframework.dao.support.PersistenceExceptionTranslator)
[2]#    org.mybatis.spring.SqlSessionUtils:getSqlSession(org.apache.ibatis.session.SqlSessionFactory)   !entry!
[2]#    org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor:invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object[])    !entry!
  • 向下
org.mybatis.spring.SqlSessionFactoryBean:scanClasses(java.lang.String,java.lang.Class)
[0]#org.mybatis.spring.SqlSessionFactoryBean:scanClasses(java.lang.String,java.lang.Class)
[1]#  org.springframework.util.StringUtils:tokenizeToStringArray(java.lang.String,java.lang.String)
[1]#  org.springframework.util.ClassUtils:convertClassNameToResourcePath(java.lang.String)
[1]#  org.springframework.core.io.support.ResourcePatternResolver:getResources(java.lang.String)
[1]#  org.springframework.core.type.classreading.MetadataReaderFactory:getMetadataReader(org.springframework.core.io.Resource)
[1]#  org.springframework.core.type.classreading.MetadataReader:getClassMetadata()
[1]#  org.springframework.core.type.ClassMetadata:getClassName()
[1]#  org.apache.ibatis.io.Resources:classForName(java.lang.String)
[2]#    org.apache.ibatis.io.ClassLoaderWrapper:classForName(java.lang.String)
[3]#      org.apache.ibatis.io.ClassLoaderWrapper:getClassLoaders(java.lang.ClassLoader)
[3]#      org.apache.ibatis.io.ClassLoaderWrapper:classForName(java.lang.String,java.lang.ClassLoader[])
[1]#  org.mybatis.spring.SqlSessionFactoryBean:lambda$scanClasses$19(org.springframework.core.io.Resource,java.lang.Throwable)