如何使用Maven Artifact Resolver列出可传递依赖项?

1cklez4t  于 2023-03-22  发布在  Maven
关注(0)|答案(1)|浏览(310)

bounty将在2天后过期。回答此问题可获得+50声望奖励。Cardinal System希望引起更多人对此问题的关注:提供一个可行的解决方案或可信的解释为什么不能提供。

我正在为我的公司开发一个应用程序,该应用程序需要为Maven项目解析依赖项。这是一个独立的应用程序,而不是Maven插件。目前我唯一要做的就是打印已解析的依赖项以确认找到它们。我使用的是Apache Maven Modelv4.0.0-alpha-2)、Apache Maven Artifact Resolverv1.8.2)和Maven Artifact Resolver Implementationv1.8.2)来支持我的奋进。
最初的设置真的是让我感到筋疲力尽的地方。我还没有找到任何更新的例子或文档。这是我起草的代码:

public static void main(String[] args)
        throws LoadException, IOException, XmlPullParserException, DependencyResolutionException {
    MavenXpp3Reader reader = new MavenXpp3Reader();
    Model model = reader.read(new FileReader(new File("C:\\Users\\lc70844\\eclipse-workspace\\test\\pom.xml")));

    DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
    DefaultRepositorySystem repositorySystem = new DefaultRepositorySystem();

    for (Dependency dependency : model.getDependencies()) {
        DependencyRequest request = new DependencyRequest();
        request.setRoot(new DefaultDependencyNode(
                new org.eclipse.aether.graph.Dependency(toArtifact(dependency), dependency.getScope())));
        DependencyResult result = repositorySystem.resolveDependencies(session, request);
        result.getArtifactResults().stream().map(a -> a.getArtifact())
                .map(a -> a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getVersion()).forEach(System.out::println);
    }
}

它抛出了一个异常,说“存储库系统会话的本地存储库管理器不能为空”。我们都知道我需要做什么。然而,DefaultRepositorySystemSession#setLocalRepositoryManager(LocalRepositoryManager)需要一个LocalRepositoryManager参数,这是我在弄清楚如何设置时遇到的麻烦。我想使用的存储库是本地存储库:%userprofile%/.m2/repository .
我发现了几个与我的问题有关的类似问题,但它们似乎有错误的上下文或正在使用已弃用的库来实现其目的。我希望有一个可靠的,最新的解决方案。
希望我至少朝着正确的方向前进。我还需要做什么才能得到我的依赖项列表?

编辑

我目前的方法是使用Maven Invoker来运行mvn dependency:list,但这只是暂时的,并不是真实的的解决方案。启动Maven进程并运行与此操作相关的所有任务需要花费太长时间。我正在努力使我的应用程序更高效,使用Maven Invoker是一种非常低效的方法。

bttbmeg0

bttbmeg01#

好吧,如果你可以访问目标pom.xml,你可以简单地执行mvn dependency:tree,这将打印所有依赖项的完整树沿着它们的作用域(显式指定和传递)。输出如下所示:

[INFO] com.tsypanov:spring-boot-benchmark:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter:jar:2.6.3:compile
[INFO] |  +- org.springframework.boot:spring-boot:jar:2.6.3:compile
[INFO] |  |  \- org.springframework:spring-context:jar:5.3.15:compile
[INFO] |  |     \- org.springframework:spring-expression:jar:5.3.15:compile
[INFO] |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.6.3:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.6.3:compile
[INFO] |  |  +- ch.qos.logback:logback-classic:jar:1.2.10:compile
[INFO] |  |  |  \- ch.qos.logback:logback-core:jar:1.2.10:compile
[INFO] |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.1:compile
[INFO] |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.17.1:compile
[INFO] |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.33:compile
...

或者,如果你需要解析输出,使用mvn dependency:listmvn dependency:build-classpath会更容易。注意,这只是打印模型,并没有告诉任何关于特定依赖是否被解析并缓存在.m2中的信息,但是你可以用mvn dependency:classpath的输出来检查这一点:就像这样分割输出行

[INFO] Dependencies classpath:
C:\Users\STsypanov\.m2\repository\org\springframework\boot\spring-boot-starter\2.6.3\spring-boot-starter-2.6.3.jar;C:\Users\STsypanov\.m2\repository\org\springframework\boot\spring-boot\2.6.3\spring-boot-2.6.3.jar;

;,然后检查每个文件是否存在:

String[] paths = classpath.split(";");
for (String path : paths) {
  var file = new File(path);
  if (file.exists()) {
    //...
  }
}

相关问题