这类似于其他问题(如this),但我希望能够使用最新的API 来做到这一点。maven-dependency-plugin:tree 详细选项已被弃用,并且在最新的 (2.5.1) 代码中没有任何作用,因此没有很好的示例说明如何做到这一点。
问问题
3077 次
2 回答
5
我相信来自jcabi-aether 的Aether
实用程序类可以帮助您获取任何 Maven 工件的所有依赖项的列表,例如:
File repo = this.session.getLocalRepository().getBasedir();
Collection<Artifact> deps = new Aether(this.getProject(), repo).resolve(
new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
JavaScopes.RUNTIME
);
如果您不在 Maven 插件之外:
File repo = new File("/tmp/local-repository");
MavenProject project = new MavenProject();
project.setRemoteProjectRepositories(
Arrays.asList(
new RemoteRepository(
"maven-central",
"default",
"http://repo1.maven.org/maven2/"
)
)
);
Collection<Artifact> deps = new Aether(project, repo).resolve(
new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
"runtime"
);
您需要的唯一依赖项是:
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-aether</artifactId>
<version>0.7.5</version>
</dependency>
于 2013-01-01T07:19:42.803 回答
0
在这里包括我的方法,因为附加步骤可能会成为您实际用例的一部分,尤其是。如果从事复合或多模块项目。
(Maven 3,我的运行时是 3.6;不直接依赖于 Aether)
就我而言,我想foo-runtime
从插件内部解析特定工件的依赖树;然而,
- 一些依赖版本仅在其父
foo-parent
POM 中可用(即在foo-runtime
自己的 POM 中不存在)。 - 父 POM 还具有其他详细信息,例如某些
foo-runtime
依赖项的排除项 - viadependencyManagement
。
所以我不得不:
- 显式加载父模型,
- 将子模型链接到它,
- 填写子模型缺少的版本号(还是不知道为什么Maven在链接父模型后没有自动解决这些),然后
- 为孩子运行依赖解决方案。
为了避免从头开始构建模型,我派生了foo-runtime
使用现有工件的模型foo-api
(在我的情况下,它始终保证存在于正在构建的 Maven 项目中)。所有这些工件都共享相同的groupId
.
@Component
public LifecycleDependencyResolver resolver;
// ...
// `artifacts` contains all artifacts of current/reactor `MavenProject` obtained via `project.getArtifacts()`
private Set<Artifact> resolveRuntimeDeps(Set<Artifact> artifacts) throws MojoExecutionException {
// foo-api will always be present; use it to derive coordinates for foo-runtime
Artifact fooApi = artifacts.stream().filter(artifact -> "foo-api".equals(artifact.getArtifactId()))
.findFirst().orElseThrow(() -> new MojoExecutionException("Unable to find foo-api"));
Collection<String> scopes = Arrays.asList("compile", "runtime");
MavenProject fooRoot = deriveProject(fooApi, "foo-parent");
Model fooRootPom = fooRoot.getModel();
MavenProject fooSrv = deriveProject(fooApi, "foo-runtime");
fooSrv.setParent(fooRoot);
// some foo-runtime deps depend on versions declared on parent pom; merge them
Map<String, Artifact> depMgt = fooRootPom.getDependencyManagement().getDependencies().stream()
.collect(Collectors.toMap(dep -> dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getType(), this::toArtifact));
for (Dependency d : fooSrv.getDependencies()) {
if (d.getVersion() == null) {
Artifact managed = depMgt.get(d.getGroupId() + ":" + d.getArtifactId() + ":" + d.getType());
if (managed != null) {
d.setVersion(managed.getVersion());
}
}
}
try {
resolver.resolveProjectDependencies(fooSrv, scopes, scopes, session, false, Collections.emptySet());
return fooSrv.getArtifacts();
} catch (LifecycleExecutionException e) {
throw new MojoExecutionException("Error resolving foo-runtime dependencies", e);
}
}
// load POM for another artifact based on foo-api JAR available in current project
private MavenProject deriveProject(Artifact fooApi, String artifactId) throws MojoExecutionException {
Model pom;
String pomPath = fooApi.getFile().getAbsolutePath().replaceAll("foo-api", artifactId).replaceAll("\\.jar$", ".pom");
try (InputStream fooRootPomData = new FileInputStream(pomPath)) {
pom = new MavenXpp3Reader().read(fooRootPomData);
pom.setPomFile(new File(pomPath));
} catch (IOException | XmlPullParserException e) {
throw new MojoExecutionException("Error loading " + artifactId + " metadata", e);
}
// set these params to avoid skips/errors during resolution
MavenProject proj = new MavenProject(pom);
proj.setArtifact(toArtifact(pom));
proj.setArtifactFilter(Objects::nonNull);
proj.setRemoteArtifactRepositories(Collections.emptyList());
return proj;
}
private Artifact toArtifact(Model model) {
return new DefaultArtifact(
Optional.ofNullable(model.getGroupId()).orElseGet(() -> model.getParent().getGroupId()), model.getArtifactId(),
Optional.ofNullable(model.getVersion()).orElseGet(() -> model.getParent().getVersion()), "compile", model.getPackaging(), null,
project.getArtifact().getArtifactHandler());
}
private Artifact toArtifact(Dependency dep) {
return new DefaultArtifact(dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), dep.getScope(), dep.getType(), dep.getClassifier(),
project.getArtifact().getArtifactHandler());
}
(我尝试了几乎所有其他建议的方法,但是所有这些方法最终都出现了一些错误。现在回想起来,我怀疑其中许多错误可能是由于我的叶子 POM 缺少某些版本号似乎(可以接受)“模型丰富”阶段——传播父版本等——是由 Maven 流程中的一些早期组件执行的;调用者在调用依赖项时必须至少部分处理这一点从头开始解析器。)
于 2022-01-23T15:36:11.517 回答