如何将java标准库从So烟尘生成的调用图中排除?

如何将java标准库从So烟尘生成的调用图中排除?,java,static-analysis,call-graph,soot,Java,Static Analysis,Call Graph,Soot,我目前正在开发一个自动代码文档工具。为此,我使用coomit构建调用图。然而,在这个调用图中似乎包含了标准java库。当然,这是不可取的,因为我只对我将生成文档的程序的实际类感兴趣 这是我用来测试调用图的程序: public static void main(String[] args) throws FileNotFoundException { List<String> argsList = new ArrayList<String>(Arr

我目前正在开发一个自动代码文档工具。为此,我使用coomit构建调用图。然而,在这个调用图中似乎包含了标准java库。当然,这是不可取的,因为我只对我将生成文档的程序的实际类感兴趣

这是我用来测试调用图的程序:

    public static void main(String[] args) throws FileNotFoundException {

        List<String> argsList = new ArrayList<String>(Arrays.asList(new String[0]));
        argsList.addAll(Arrays.asList(new String[]{
            "-w",
            "-no-bodies-for-excluded",
            "-process-dir",
            args[1], //directory with the java files
            "-src-prec",
            "java",
            "-main-class",
            args[2] //main class
        }));

        String[] trueArgs = argsList.toArray(new String[0]);
        Main.v().run(trueArgs);
        CallGraph cg = Scene.v().getCallGraph();
        visit(cg , Scene.v().getEntryPoints().get(0));
    }
publicstaticvoidmain(字符串[]args)抛出FileNotFoundException{
List argsList=newarraylist(Arrays.asList(新字符串[0]);
argsList.addAll(Arrays.asList)(新字符串[]){
“-w”,
“-没有排除的机构”,
“-进程目录”,
args[1],//包含java文件的目录
“-src prec”,
“爪哇”,
“-主类”,
args[2]//主类
}));
字符串[]trueArgs=argsList.toArray(新字符串[0]);
Main.v().run(trueArgs);
CallGraph cg=Scene.v().getCallGraph();
访问(cg,Scene.v().getEntryPoints().get(0));
}
使用以下函数迭代调用图(取自):

私有静态无效访问(调用图cg,SootMethod方法){
字符串标识符=方法.getSignature();
visitored.put(method.getSignature(),true);
dot.drawNode(标识符);
//迭代未访问的父母
迭代器ptargets=新源(cg.edgesInto(方法));
if(ptargets!=null){
while(ptargets.hasNext()){
SootMethod parent=(SootMethod)ptargets.next();
如果(!visted.containsKey(parent.getSignature()))访问(cg,parent);
}
}
//迭代未访问的儿童
迭代器ctargets=新目标(cg.edgesutof(方法));
如果(ctargets!=null){
while(ctargets.hasNext()){
SootMethod子对象=(SootMethod)ctargets.next();
dot.draudge(标识符,child.getSignature());
System.out.println(方法+“可以调用”+子对象);
如果(!visted.containsKey(child.getSignature()))访问(cg,child);
}
}
}
然而,在测试过程中,我一直在记录此类通话:

[...]
<callgraphs.A: void <init>()> may call <java.lang.Object: void <init>()>
<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.Runnable)> may call <java.lang.Object: void <clinit>()>
<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)> may call <java.lang.Object: void <clinit>()>
<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)> may call <java.lang.Object: void <init>()>
<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)> may call <java.lang.Thread: void init(java.lang.ThreadGroup,java.lang.Runnable,java.lang.String,long)>
<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)> may call <java.lang.Object: void <init>()>
[...]
[…]
可以打电话
可以打电话
可以打电话
可以打电话
可以打电话
可以打电话
[...]
接下来是java库之间的大量调用


有没有一种方法可以让您忽略标准java库?

好的,我找到了一个解决方案

我们只是抑制java包中类的
visit
调用

因此,使用
child.isJavaLibraryMethod()
检查它是否来自java包

如果它来自java包,我们就不使用该类调用
visit
,因此通过对父调用和子调用添加此检查并抑制输出,我们可以得到正确的调用图。(另外,由于您不再遍历java库,因此它的速度要快得多

因此,代码更改为:

private static void visit(CallGraph cg, SootMethod method) {
          String identifier = method.getSignature();
          visited.put(method.getSignature(), true);
          dot.drawNode(identifier);
          // iterate over unvisited parents
          Iterator<MethodOrMethodContext> ptargets = new Sources(cg.edgesInto(method));
          if (ptargets != null) {
            while (ptargets.hasNext()) {
                SootMethod parent = (SootMethod) ptargets.next();
                if (!visited.containsKey(parent.getSignature()) && !parent.isJavaLibraryMethod()) visit(cg, parent);
            }
          }
          // iterate over unvisited children
          Iterator<MethodOrMethodContext> ctargets = new Targets(cg.edgesOutOf(method));
          if (ctargets != null) {
            while (ctargets.hasNext()) {
               SootMethod child = (SootMethod) ctargets.next();
               dot.drawEdge(identifier, child.getSignature());
               if (!child.isJavaLibraryMethod())System.out.println(method + " may call " + child);
               if (!visited.containsKey(child.getSignature()) && !child.isJavaLibraryMethod()) visit(cg, child);
            }
          }
    }
私有静态无效访问(调用图cg,SootMethod方法){
字符串标识符=方法.getSignature();
visitored.put(method.getSignature(),true);
dot.drawNode(标识符);
//迭代未访问的父母
迭代器ptargets=新源(cg.edgesInto(方法));
if(ptargets!=null){
while(ptargets.hasNext()){
SootMethod parent=(SootMethod)ptargets.next();
如果(!visitored.containsKey(parent.getSignature())和(!parent.isJavaLibraryMethod())访问(cg,parent);
}
}
//迭代未访问的儿童
迭代器ctargets=新目标(cg.edgesutof(方法));
如果(ctargets!=null){
while(ctargets.hasNext()){
SootMethod子对象=(SootMethod)ctargets.next();
dot.draudge(标识符,child.getSignature());
如果(!child.isJavaLibraryMethod())System.out.println(方法+)可以调用“+child”;
如果(!visted.containsKey(child.getSignature())和(!child.isJavaLibraryMethod())访问(cg,child);
}
}
}
private static void visit(CallGraph cg, SootMethod method) {
          String identifier = method.getSignature();
          visited.put(method.getSignature(), true);
          dot.drawNode(identifier);
          // iterate over unvisited parents
          Iterator<MethodOrMethodContext> ptargets = new Sources(cg.edgesInto(method));
          if (ptargets != null) {
            while (ptargets.hasNext()) {
                SootMethod parent = (SootMethod) ptargets.next();
                if (!visited.containsKey(parent.getSignature()) && !parent.isJavaLibraryMethod()) visit(cg, parent);
            }
          }
          // iterate over unvisited children
          Iterator<MethodOrMethodContext> ctargets = new Targets(cg.edgesOutOf(method));
          if (ctargets != null) {
            while (ctargets.hasNext()) {
               SootMethod child = (SootMethod) ctargets.next();
               dot.drawEdge(identifier, child.getSignature());
               if (!child.isJavaLibraryMethod())System.out.println(method + " may call " + child);
               if (!visited.containsKey(child.getSignature()) && !child.isJavaLibraryMethod()) visit(cg, child);
            }
          }
    }