如何获得 EAR 的完整依赖树?

How to get an EAR's full dependency tree?

这是我的用例:我想获得我的 EAR 的完整依赖关系树,具有以下范围:编译、运行时、测试。

不幸的是,Maven 的依赖插件只显示 WARs 作为简单的依赖,没有它们的传递依赖。

foo:bar-ear:ear:1.13.0-SNAPSHOT
+- foo:bar-web:war:1.13.0-SNAPSHOT:compile
+- foo:bar-web-service:war:1.13.0-SNAPSHOT:compile
+- foo:bar-business:ejb:1.13.0-SNAPSHOT:compile
|  +- foo:base-api:ejb:2.22.0-SNAPSHOT:compile
...

所以我需要在 Maven 插件(使用 3.0.4)中获取完整的依赖关系树(包括 WAR 的依赖关系)。

我用 Aether 试过,但无法正确设置示波器。接下来我尝试使用 "old-style" Maven 依赖解析(查看依赖插件的代码),但是 org.apache.maven.shared:maven-dependency-tree 只适用于 MavenProject,但我应该告诉 DependencyGraphBuilder获取任何 Artifact.

的依赖项

谁能给我指出正确的方向?

最后,这就是 Maven API 的工作原理。我使用了 Google Guava 和 Apache Commons Lang 3,所以如果您不熟悉这些库,请询问。

/**
 * Gets all dependencies for an artifact, including the ones from WAR dependencies.
 * @param artifact The artifact
 * @return The dependencies, where the key is the artifactId and the values are all of its artifacts (different
 * versions, different scopes)
 * @throws MojoExecutionException if the dependencies can't be fetched
 */
protected Multimap<String, Artifact> getAllDependencies(final Artifact artifact) throws MojoExecutionException {
  Multimap<String, Artifact> projectDependencies = getDependencies(artifact);
  Multimap<String, Artifact> allDependencies = ArrayListMultimap.create(projectDependencies);

  for (Artifact dependency : projectDependencies.values()) {
    if (dependency.getType().equals("war")) {
      Multimap<String, Artifact> warDependencies = getDependencies(dependency);
      for (Artifact warArtifact : warDependencies.values()) {
        if (!containsArtifact(allDependencies, warArtifact)) {
          allDependencies.put(warArtifact.getArtifactId(), warArtifact);
        }
      }
    }
  }
  return allDependencies;
}

/**
 * Gets the dependencies for an artifact.
 * @param artifact The artifact
 * @return The dependencies, where the key is the artifactId and the values are all of its artifacts (different
 * versions, different scopes)
 * @throws MojoExecutionException if the dependencies can't be fetched
 */
protected Multimap<String, Artifact> getDependencies(final Artifact artifact) throws MojoExecutionException {
  try {
    Artifact pomArtifact = this.repositorySystem.createProjectArtifact(artifact.getGroupId(),
        artifact.getArtifactId(), artifact.getVersion());
    MavenProject mavenProject = this.mavenProjectBuilder.buildFromRepository(pomArtifact, this.remoteRepositories,
        this.localRepository);

    Multimap<String, Artifact> dependencies = ArrayListMultimap.create();
    DependencyNode rootNode = this.dependencyGraphBuilder.buildDependencyGraph(mavenProject, this.artifactFilter);

    CollectingDependencyNodeVisitor visitor = new CollectingDependencyNodeVisitor();
    rootNode.accept(visitor);

    for (DependencyNode dependencyNode : visitor.getNodes()) {
      Artifact dependencyArtifact = dependencyNode.getArtifact();
      if (!containsArtifact(dependencies, dependencyArtifact)) {
        dependencies.put(dependencyArtifact.getArtifactId(), dependencyArtifact);
      }
    }
    return dependencies;
  } catch (Exception e) {
    throw new MojoExecutionException("Can't get dependencies for " + artifact, e);
  }
}

/**
 * Shows whether an artifact is contained in the given artifacts.
 * @param artifacts The artifacts
 * @param artifact The artifact to check
 * @return {@code true} if the artifact is contained, otherwise {@code false}
 */
protected boolean containsArtifact(final Multimap<String, Artifact> artifacts, final Artifact artifact) {
  String artifactId = artifact.getArtifactId();
  if (!artifacts.containsKey(artifactId)) {
    return false;
  } else {
    String coordinates = getCoordinates(artifact);
    for (Artifact existingArtifact : artifacts.get(artifactId)) {
      String existingCoordinates = getCoordinates(existingArtifact);
      if (coordinates.equals(existingCoordinates)) {
        return true;
      }
    }
    return false;
  }
}

/**
 * Gets the Maven coordinates for an artifact.
 * @param artifact The artifact
 * @return The Maven coordinates
 */
protected static String getCoordinates(final Artifact artifact) {
  List<String> parts = Lists.newArrayList(artifact.getGroupId(), artifact.getArtifactId(), artifact.getType(),
      artifact.getVersion(), artifact.getScope());
  return StringUtils.join(parts, ":");
}