Pregunta

En mi plug-in que necesito para procesar la jerarquía de dependencias y obtener información (groupId, artifactId, versión, etc.) sobre cada dependencia y si estaba excluido. ¿Cuál es la mejor manera de hacer esto?

¿Fue útil?

Solución

El complemento de la dependencia tiene el árbol href="http://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html" objetivo que hace la mayor parte de este trabajo. Se procesa una MavenProject utilizando el DependencyTreeBuilder, este devuelve un DependencyNode con información jerárquica de las dependencias resueltas (y sus dependencias transitivas).

Puede copiar la mayor parte del código directamente desde el TreeMojo. Utiliza el CollectingDependencyNodeVisitor a recorrer el árbol y producir una List de todos los nodos.

Puede acceder a la Artifact para el nodo llamando getArtifact(), a continuación, obtener la información artefacto, según sea necesario. Para obtener la razón de la exclusión, DependencyNode tiene un método getState() que devuelve un int que indica si la dependencia se ha incluido, o si no lo que la razón de su omisión fue (no son constantes en la clase DependencyNode para comprobar el valor de retorno en contra)

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

Otros consejos

Se puede usar MavenProject # getDependencyArtifacts () o MavenProject # getDependencies () (la que más tarde vuelve dependencias también transitivos).

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

       ...
    }

}

No estoy totalmente seguro pero creo que ambos métodos devuelven una colección de artefactos implementaciones que exponen a los captadores de groupId, artifactId, versión, etc.

Esta es una puesta al día, Maven3 ejemplo sobre cómo conseguir todas las dependencias (incluyendo transitivo), así como tener acceso a los mismos archivos (si por ejemplo hay que añadir las rutas de acceso a una ruta de clase).

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

El cambio de los parámetros en el Mojo es una pieza muy importante que me estaba perdiendo. Sin ella, líneas como las siguientes:

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

sólo devolverá el directorio de clases, no el camino que espera.

Cambio de la requiresDependencyCollection y requiresDependencyResolution a diferentes valores le permitirá cambiar el alcance de lo que se quiere agarrar. El experta en la documentación puede proporcionar más detalles.

Trate de usar Aether clase de utilidad de jcabi-éter para obtener una lista de todas las dependencias de cualquier artefacto:

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

¿Por qué no volver a todas las dependencias (tanto los directos y transitivos) y compruebe si la exclusión?

@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 del éter, no es muestra aquí: https://docs.sonatype.org/display/AETHER/Home

Para Maven 3 puede utilizar DependencyGraphBuilder. Lo hace más o menos lo mismo que DependencyTreeBuilder.

Aquí es el ejemplo

    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();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top