查找 Java Class 的所有传递依赖项,包括仅通过其接口使用的实现 类
Find all transitive dependencies of Java Class including implementation classes used only via their interfaces
我的目标是列出我项目的 public API classes 的所有传递依赖项,并在发生任何代码更改时使用它来集中测试工作对那些依赖项。
例如:
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.html and http://depfind.sourceforge.net/ - 它们很有前途,但似乎并没有完全解决问题。对于这两种工具,似乎如果 class 依赖于一个接口,则没有内置方法将该接口的实现作为传递依赖项包含在内。
有没有办法在不进行大量定制的情况下从任何工具中提取此信息?
您可以根据需要使用 JArchitect。
右键单击 UI 中任意位置的方法,然后 select 打开菜单:Select 方法... > ...正在使用我(直接或间接) 导致代码查询,如:
from m in Methods
let depth0 = m.DepthOfIsUsing("myNamespace.MyClass.MyMethod()")
where depth0 >= 0 orderby depth0
select new { m, depth0 }
问题是此类查询提供了间接用法,但不查找通过接口发生的调用(或在基[=36=中声明的重写方法) ]).
希望可以通过此查询获得您所要求的内容:
// 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() 的调用 select 递归间接调用。
- 对属性IMethod.OverriddensBase的调用,顾名思义。对于方法 M this returns 在基础 class 或接口中声明的所有方法的可枚举,被 M[=29= 覆盖].
我的目标是列出我项目的 public API classes 的所有传递依赖项,并在发生任何代码更改时使用它来集中测试工作对那些依赖项。
例如:
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.html and http://depfind.sourceforge.net/ - 它们很有前途,但似乎并没有完全解决问题。对于这两种工具,似乎如果 class 依赖于一个接口,则没有内置方法将该接口的实现作为传递依赖项包含在内。
有没有办法在不进行大量定制的情况下从任何工具中提取此信息?
您可以根据需要使用 JArchitect。 右键单击 UI 中任意位置的方法,然后 select 打开菜单:Select 方法... > ...正在使用我(直接或间接) 导致代码查询,如:
from m in Methods
let depth0 = m.DepthOfIsUsing("myNamespace.MyClass.MyMethod()")
where depth0 >= 0 orderby depth0
select new { m, depth0 }
问题是此类查询提供了间接用法,但不查找通过接口发生的调用(或在基[=36=中声明的重写方法) ]).
希望可以通过此查询获得您所要求的内容:
// 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() 的调用 select 递归间接调用。
- 对属性IMethod.OverriddensBase的调用,顾名思义。对于方法 M this returns 在基础 class 或接口中声明的所有方法的可枚举,被 M[=29= 覆盖].