2017-08-11 122 views
2

我的目标是列出项目的公共API类的所有传递依赖项,并使用它来集中测试工作以防止发生任何代码更改到那些依赖关系。查找Java类的所有传递依赖项,包括仅通过其接口使用的实现类

例如:

class MyApi { 
    MyDao md; 
    public void methodA() { 
     //do something with md; 
    } 
} 

interface MyDao { } 

class MyDaoImpl implements MyDao { } 

所以,如果我知道MyDaoImpl已被修改(比如从提交历史),我知道MyApi.methodA使用MyDaoImpl,然后我的测试应重点检查它。我需要MyApi.methodA()的依赖项列表,包括MyDao和MyDaoImpl。

到目前为止,我已经尝试了两种工具 - https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.htmlhttp://depfind.sourceforge.net/ - 它们很有前途,但似乎并未完全解决问题。对于这两种工具,似乎如果一个类依赖于一个接口,就没有内建的方式将该接口的实现包含为传递依赖。

有没有一种方法可以从任何工具中获取这些信息而不需要大量定制?

+0

你应该在你的方法中加入'md = new MyDaoImpl()'。否则'MyDaoImpl'没有连接到你的应用程序。 – Nathan

+0

实际的代码使用spring来注入实现类,所以确实没有新的MyDaoImpl()。我正在寻找一些方法来吸引MyApi正在使用的所有接口实现,即使没有直接在代码中创建。 – ab2000

回答

1

您可以使用JArchitect来满足您的需求。 右键单击的方法在任何地方的用户界面,然后选择菜单:选择方法...> ...正在使用我的(直接或间接)导致代码查询,如:

from m in Methods 
let depth0 = m.DepthOfIsUsing("myNamespace.MyClass.MyMethod()") 
where depth0 >= 0 orderby depth0 
select new { m, depth0 } 

的问题是这样的查询给出了间接使用,但不寻找通过接口(或在基类中声明的重写方法)发生的调用

希望你问了能与此查询获得:

// Retrieve the target method by name 
let methodTarget = Methods.WithFullName(""myNamespace.MyClass.MyMethod()"").Single() 

// Build a ICodeMetric<IMethod,ushort> representing the depth of indirect 
// call of the target method. 
let indirectCallDepth = 
    methodTarget.ToEnumerable() 
    .FillIterative(
     methods => methods.SelectMany(
      m => m.MethodsCallingMe.Union(m.OverriddensBase))) 

from m in indirectCallDepth.DefinitionDomain 
select new { m, callDepth = indirectCallDepth[m] } 

两个此查询的基石是:

  • 到FillIterative()的调用递归选择间接呼叫。顾名思义,对属性IMethod.OverriddensBase的调用是
  • 。对于方法M这将返回在基类或接口中声明的所有方法的枚举,由M覆盖。
+0

谢谢James,JArchitect查询似乎按照我的预期工作。 – ab2000

相关问题