[英]How to get a list of Java class dependencies programmatically
本质上,我在问类似这样的问题: 如何获取主要 class 的 Java class 依赖项列表? 但我想用 Java API 来做。 我不想执行jdeps
并刮掉 output。
如果它使用https://github.com/classgraph/classgraph ,则加分,因为我们的项目已经使用了该库,并且它非常适合在不实际实例化它处理的所有内容的情况下扫描类。
哦,这将仅限于在 JDK 8 上工作。
[更新]
这里有一点背景。 假设我有一个捆绑的应用程序。 也许是 Spring Boot 应用程序或可以部署到 Cloud Foundry 或 Heroku 等云平台的东西。 该应用程序可能包含框架 jars(如 Spring)、实用程序 jars(日志记录、模板、json/xml 处理等)、应用程序域类以及所有必要的传递依赖项。 假设这全部都捆绑到 uber-jar 中或通过类路径引用。
我的用例是:给定一个 class 和 uber-jar/classpath,我给定的 class 的子集(在那个 uber-jar 之外)是什么?
事实证明,我可以用classgraph
做我想做的事。 关键是设置enableInterClassDependencies
。 给定 class,以下将处理该 class 的所有依赖项,并确定哪些 jars 包含相关的依赖类:
import java.net.URI;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ClassInfoList;
import io.github.classgraph.ScanResult;
public class DependencyFinder {
private final String clazz;
public DependencyFinder(String clazz) {
this.clazz = clazz;
}
public Set<URI> process() {
ScanResult scanResult = new ClassGraph()
.whitelistPackages()
.enableInterClassDependencies()
.scan();
ClassInfo rootClass = scanResult.getClassInfo(clazz);
Map<ClassInfo, ClassInfoList> dependencyMap = scanResult.getClassDependencyMap();
Set<URI> results = new HashSet<>();
Set<ClassInfo> seen = new HashSet<>();
accumulateJars(new HashSet<>(dependencyMap.get(rootClass)), dependencyMap, results, seen);
return results;
}
private void accumulateJars(Set<ClassInfo> roots, Map<ClassInfo, ClassInfoList> dependencies, Set<URI> accumulated, Set<ClassInfo> seen) {
Set<ClassInfo> nextRoots = new HashSet<>();
for (ClassInfo info : roots) {
if (seen.contains(info)) {
continue;
}
accumulated.add(info.getClasspathElementURI());
seen.add(info);
nextRoots.addAll(dependencies.get(info));
}
if (nextRoots.size() > 0) {
accumulateJars(nextRoots, dependencies, accumulated, seen);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.