Domanda

Nel mio plug-in ho bisogno di elaborare la gerarchia delle dipendenze e ottenere informazioni (groupId, artifactId, versione ecc) su ogni dipendenza e se è stata esclusa. Qual è il modo migliore per fare questo?

È stato utile?

Soluzione

Il plugin di dipendenza ha la obiettivo che fa la maggior parte di questo lavoro. Si elabora un MavenProject utilizzando il DependencyTreeBuilder, questo restituisce un DependencyNode con informazioni gerarchiche sulle dipendenze risolti (e le loro dipendenze transitive).

È possibile copiare la maggior parte del codice direttamente dal TreeMojo. Esso utilizza il CollectingDependencyNodeVisitor per attraversare l'albero e produrre una List di tutti i nodi.

È possibile accedere al Artifact per il nodo chiamando getArtifact(), quindi ottenere le informazioni artefatto, se necessario. Per ottenere il motivo di esclusione, DependencyNode ha un metodo getState() che restituisce un int che indica se la dipendenza è stato incluso, o se non ciò che il motivo per l'omissione era (ci sono costanti nella classe DependencyNode per controllare il valore di ritorno contro)

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

Altri suggerimenti

Si potrebbe utilizzare noreferrer MavenProject # getDependencyArtifacts () o noreferrer MavenProject # getDependencies () (quella successiva torna dipendenze anche transitive).

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

       ...
    }

}

Non sono del tutto sicuro, ma penso che entrambi i metodi restituiscono un insieme di implementazioni Artefatto che espongono getter per groupId, artifactId, versione, ecc.

Ecco un aggiornato, Maven3 esempio su come ottenere tutte le dipendenze (compresi transitiva), così come avere accesso ai file stessi (se per esempio necessario aggiungere i percorsi per un percorso di classe).

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

La modifica dei parametri del Mojo è un pezzo molto importante che mi mancava. Senza di essa, le linee come le seguenti:

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

restituisce solo la directory di classi, non il percorso che ci si aspetta.

La modifica della requiresDependencyCollection e requiresDependencyResolution a valori diversi vi permetterà di modificare la portata di ciò che si vuole afferrare. Il esperto di documentazione in grado di fornire ulteriori dettagli.

Prova ad utilizzare Aether classe di utilità da jcabi-etere per ottenere un elenco di tutte le dipendenze di qualsiasi manufatto:

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

Perché non tornare tutte le dipendenze (quelli sia diretto e transitivo) e verificare la presenza di esclusione?

@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 uso dell'etere, non v'è campione qui: https://docs.sonatype.org/display/AETHER/Home

Per Maven 3 è possibile utilizzare DependencyGraphBuilder. Si fa più o meno la stessa cosa di DependencyTreeBuilder.

Ecco l'esempio

    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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top