Soot:源文件更改后重新加载类

时间:2017-06-08 16:26:24

标签: java static-analysis intellij-plugin soot

我正在编写一个IntelliJ-Plugin来分析java程序代码。因此,我使用Soot来编写静态分析。每次用户触发我的插件的分析操作时,我都会采用当前上下文的当前VirtualFile

FileEditorManager manager = FileEditorManager.getInstance(e.getProject());
VirtualFile files[] = manager.getSelectedFiles();
toAnalyse = files[0]; [...]

当我检查此文件的内容时,将应用所有更改。在此之后我加载了我想在Soot中分析的课程。

String dir =  toAnalyse.getParent().getPath() ;
Options.v().setPhaseOption("jb", "use-original-names");
Options.v().set_soot_classpath( System.getProperty("java.home")+";"+ dir);
c = Scene.v().loadClassAndSupport(name);
/*no analyse c*/

这对我来说很有效。但现在我的问题: 如果我改变某事。在我的插件的测试实例中,再次触发相同的分析,没有任何变化。

  

到目前为止我尝试了什么?

我设置了以下选项

Options.v().set_dump_body( Arrays.asList("jb"));
Options.v().set_dump_cfg( Arrays.asList("jb"));
Options.v().set_allow_phantom_refs(true);
Options.v().set_whole_program(true);

我也手动删除了所有课程

像这样:

Chain<SootClass> classes = Scene.v().getClasses();
Stack<SootClass> stack = new Stack<>();
for(SootClass s : classes)
    stack.push(s);
while(!stack.empty())
    Scene.v().removeClass(stack.pop());

再次启动该程序。

1 个答案:

答案 0 :(得分:4)

我解决了这个问题。

@Aspect
@Component
public class ControllerResponseValidator {

    Logger logger = Logger.getLogger(ControllerResponseValidator.class);

    @Autowired
    private Validator validator;

    @AfterReturning(pointcut = "execution(* com.example.controller.*.*(..))", returning = "result")
    public void validateResponse(JoinPoint joinPoint, Object result) {
        validateResponse(result);
    }

    private void validateResponse(Object object) {

        Set<ConstraintViolation<Object>> validationResults = validator.validate(object);

        if (validationResults.size() > 0) {

            StringBuffer sb = new StringBuffer();

            for (ConstraintViolation<Object> error : validationResults) {
                sb.append(error.getPropertyPath()).append(" - ").append(error.getMessage()).append("\n");
            }

            String msg = sb.toString();
            logger.error(msg);
            throw new RestException(HttpStatus.INTERNAL_SERVER_ERROR, msg);
        }
    }
}

SootClass c = Scene.v().loadClassAndSupport(name); // ... c.setResolvingLevel(0); G.reset(); 重置所有单例实例。 因此,通过再次调用此操作将覆盖所有缓存的结果。

G.reset()
在致电public static Scene v() { return G.v().soot_Scene(); } 后,

this.instance_soot_Scenenull

因此以下代码:

G.reset()

返回一个带有空结果缓存的新实例。