Comment accéder à la hiérarchie de dépendances de Maven dans un plugin

dans mon plugin je dois traiter la hiérarchie de dépendances et obtenir des informations (groupId, artifactId, version etc) sur chaque dépendance et si elle a été exclue. Quelle est la meilleure façon de le faire?

33
demandé sur ArtB 2009-09-29 15:36:49

7 réponses

le plugin de dépendances a le arbre but Cela fait la plus grande partie de ce travail. Il traite d'un MavenProjectDependencyTreeBuilder, il renvoie un DependencyNode avec des informations hiérarchiques sur les dépendances résolues (et leurs dépendances transitives).

vous pouvez copier une grande partie du code directement à partir du TreeMojo. Il utilise le CollectingDependencyNodeVisitor pour traverser l'arbre et produire un List de tous les noeuds.

vous pouvez accéder au Artifact pour le noeud en appelant getArtifact(), puis obtenir l'objet d'informations que nécessaire. Pour obtenir la raison de l'exclusion,DependencyNode a un getState() méthode qui renvoie un int indiquant si la dépendance a été incluse, ou si ce n'est pas la raison pour laquelle elle a été omise (il y a des constantes dans la classe DependencyNode pour vérifier la valeur de retour)

//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();
    }
}
27
répondu Rich Seller 2016-04-25 16:10:35

Vous pouvez utiliser MavenProject#getDependencyArtifacts () ou MavenProject#getDependencies () (la dernière renvoie aussi les dépendances transitives).

/**
 * 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();

       ...
    }

}

Je ne suis pas totalement sûr mais je pense que les deux méthodes renvoient une collection de Artefact implémentations qui exposent des getters pour groupId, artifactId, version, etc.

18
répondu Pascal Thivent 2016-04-25 16:10:57

voici un exemple mis à jour, Maven3 sur la façon d'obtenir toutes les dépendances (y compris transitive) ainsi que l'accès aux fichiers eux-mêmes (si vous avez besoin par exemple d'ajouter les chemins à un classpath).

// 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.
    }
  }
}

changer les paramètres du Mojo est une pièce très importante que je manquais. Sans elle, les lignes comme suit:

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

ne retournera que le répertoire des classes, pas le chemin que vous attendez.

le Changement de la requiresDependencyCollection et requiresdependencerésolution à différentes valeurs vous permettront de changer la portée de ce que vous voulez saisir. Maven documentation peut fournir plus de détails.

9
répondu wrestang 2017-10-17 09:27:36

Essayez d'utiliser Aether classe d'utilité de jcabi-aether pour obtenir une liste de toutes les dépendances de tout artefact:

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
);
5
répondu yegor256 2016-04-25 16:11:14

Maven 3 Utilisez l'éther, il y a un échantillon ici : https://docs.sonatype.org/display/AETHER/Home

3
répondu Yann Le Moigne 2012-08-29 18:52:03

pourquoi ne pas simplement récupérer toutes les dépendances (directes et transitoires) et vérifier l'exclusion?

@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) ) { ... }
  }
}
3
répondu kane 2016-02-03 19:23:16

pour Maven 3 vous pouvez utiliser DependencyGraphBuilder. Il fait à peu près la même chose que DependencyTreeBuilder.

Voici l'exemple

    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();
}
1
répondu poojaN 2017-10-17 09:39:39