Как получить доступ к иерархии зависимости Maven в плагина

StackOverflow https://stackoverflow.com/questions/1492000

Вопрос

В моем плагине мне нужно обработать иерархию зависимости и получить информацию (GroupId, Artifactid, версия и т. Д.) О каждой зависимости и, если она была исключена. Как лучше всего это сделать?

Это было полезно?

Решение

Плагин зависимости имеет Цель дерева Это делает большую часть этой работы. Он обрабатывает а MavenProject с использованием DependencyTreeBuilder, это возвращает DependencyNode с иерархической информацией о разрешенных зависимостях (и их переходных зависимостях).

Вы можете скопировать большую часть кода непосредственно из TreeMojo. Он использует CollectingDependencyNodeVisitor пересекать дерево и произвести List из всех узлов.

Вы можете получить доступ к Artifact для узла, вызывая getArtifact(), затем получите информацию о артефакте по мере необходимости. Чтобы получить причину исключения, DependencyNode имеет getState() Метод, который возвращает int, указывающий, была ли зависимость включена, или не то, что причина его пропуска (в классе зависимости есть константы, чтобы проверить возвратное значение против)

//All components need this annotation, omitted for brevity

/**
 * @component
 * @required
 * @readonly
 */
private ArtifactFactory artifactFactory;
private ArtifactMetadataSource artifactMetadataSource;
private ArtifactCollector artifactCollector;
private DependencyTreeBuilder treeBuilder;
private ArtifactRepository localRepository;
private MavenProject project;

public void execute() throws MojoExecutionException, MojoFailureException {
    try {
        ArtifactFilter artifactFilter = new ScopeArtifactFilter(null);

        DependencyNode rootNode = treeBuilder.buildDependencyTree(project,
                localRepository, artifactFactory, artifactMetadataSource,
                artifactFilter, artifactCollector);

        CollectingDependencyNodeVisitor visitor = 
            new CollectingDependencyNodeVisitor();

        rootNode.accept(visitor);

        List<DependencyNode> nodes = visitor.getNodes();
        for (DependencyNode dependencyNode : nodes) {
            int state = dependencyNode.getState();
            Artifact artifact = dependencyNode.getArtifact();
            if(state == DependencyNode.INCLUDED) {                    
                //...
            } 
        }
    } catch (DependencyTreeBuilderException e) {
        // TODO handle exception
        e.printStackTrace();
    }
}

Другие советы

Вы могли бы использовать MavenProject#getDependencyArtifacts () или же MavenProject#getDepeDendenties () (Поздний возвращает также переходные зависимости).

/**
 * Test Mojo
 *
 * @goal test
 * @requiresDependencyResolution compile
 */
public class TestMojo extends AbstractMojo {

    /**
     * The Maven Project.
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project = null;

    /**
     * Execute Mojo.
     *
     * @throws MojoExecutionException If an error occurs.
     * @throws MojoFailureException If an error occurs.
     */
    public void execute() throws MojoExecutionException,
MojoFailureException {

        ...

        Set dependencies = project.getDependencies();

       ...
    }

}

Я не совсем уверен, но я думаю, что оба метода возвращают коллекцию Артефакт Реализации, которые разоблачают Getters для GroupId, Artifactid, версии и т. Д.

Вот общий пример Maven3 о том, как получить все зависимости (включая транзитив), а также иметь доступ к самим файлам (если вам, например, нужно добавить пути в городскую дорожку).

// Default phase is not necessarily important.
// Both requiresDependencyCollection and requiresDependencyResolution are extremely important however!
@Mojo(name = "simple", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class SimpleMojo extends AbstractMojo {
  @Parameter(defaultValue = "${project}", readonly = true)
  private MavenProject mavenProject;

  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {
    for (final Artifact artifact : mavenProject.getArtifacts()) {
      // Do whatever you need here.
      // If having the actual file (artifact.getFile()) is not important, you do not need requiresDependencyResolution.
    }
  }
}

Изменение параметров в моджо - очень важная часть, которую мне не хватало. Без этого строки, такие как следующие:

@Parameter(defaultValue = "${project.compileClasspathElements}", readonly = true, required = true)
private List<String> compilePath;

Вернут только каталог классов, а не путь, который вы ожидаете.

Изменение требуемой случайности и требует возможности длязависимости в разных значениях, чтобы вы могли изменить объем того, что вы хотите захватить. А Maven документация может предоставить более подробную информацию.

Попробуй использовать Aether Утилита класса от Jcabi-Ather Чтобы получить список всех зависимостей от любого артефакта:

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
);

Почему бы просто не вернуть все зависимости (как прямые, так и переходные) и проверить на наличие исключения?

@Parameter(property = "project", required = true, readonly = true)
private MavenProject project;

public void execute() throws MojoExecutionException
{
  for (Artifact a : project.getArtifacts()) {
    if( a.getScope().equals(Artifact.SCOPE_TEST) ) { ... }
    if( a.getScope().equals(Artifact.SCOPE_PROVIDED) ) { ... }
    if( a.getScope().equals(Artifact.SCOPE_RUNTIME) ) { ... }
  }
}

Maven 3 используйте Aether, здесь есть образец:https://docs.sonatype.org/display/aether/home

Для Maven 3 вы можете использовать DevingGraphBuilder. Это делает почти то же самое, что и зависимость.

Вот пример

    import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
    import org.apache.maven.artifact.resolver.filter.IncludesArtifactFilter;
    import org.apache.maven.execution.MavenSession;
    import org.apache.maven.model.Dependency;
    import org.apache.maven.plugins.annotations.ResolutionScope;
    import org.apache.maven.plugins.annotations.LifecyclePhase;
    import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;

    import org.apache.maven.shared.dependency.graph.DependencyNode;
    import org.apache.maven.shared.dependency.graph.traversal.CollectingDependencyNodeVisitor;

    public class AnanlyzeTransitiveDependencyMojo extends AbstractMojo{

        @Parameter(defaultValue = "${project}", readonly = true, required = true)
        private MavenProject project;

        @Parameter(defaultValue = "${session}", readonly = true, required = true)
        private MavenSession session;

        @Component(hint="maven3")
        private DependencyGraphBuilder dependencyGraphBuilder;

        @Override
        public void execute() throws MojoExecutionException, MojoFailureException {
    // If you want to filter out certain dependencies.
             ArtifactFilter artifactFilter = new IncludesArtifactFilter("groupId:artifactId:version");
             ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
             buildingRequest.setProject(project);
            try{
               DependencyNode depenGraphRootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, artifactFilter);
               CollectingDependencyNodeVisitor visitor = new  CollectingDependencyNodeVisitor();
               depenGraphRootNode.accept(visitor);
               List<DependencyNode> children = visitor.getNodes();

               getLog().info("CHILDREN ARE :");
               for(DependencyNode node : children) {
                   Artifact atf = node.getArtifact();
            }
}catch(Exception e) {
    e.printStackTrace();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top