Frage

In meinem Plugin muss ich die Abhängigkeitshierarchie verarbeiten und Informationen (Groupid, Artefactid, Version usw.) zu jeder Abhängigkeit erhalten und wenn sie ausgeschlossen wurde. Was ist der beste Weg, dies zu tun?

War es hilfreich?

Lösung

Das Abhängigkeits -Plugin hat das Baumziel Das macht das meiste dieser Arbeiten. Es verarbeitet a MavenProject Verwendung der DependencyTreeBuilder, Dies gibt a zurück DependencyNode mit hierarchischen Informationen über die gelösten Abhängigkeiten (und ihre transitiven Abhängigkeiten).

Sie können einen Großteil des Code direkt aus dem Treemojo kopieren. Es verwendet das CollectingDependencyNodeVisitor Um den Baum zu durchqueren und a zu produzieren List von allen Knoten.

Sie können auf die zugreifen Artifact Für den Knoten durch Anrufe getArtifact(), Holen Sie sich dann die Artefaktinformationen nach Bedarf. Um den Ausschlussgrund zu bekommen, DependencyNode hat ein getState() Methode, die ein int zurückgibt, das angibt, ob die Abhängigkeit enthalten ist, oder wenn nicht, was der Grund für das Auslassen des Verhaltens war (es gibt Konstanten in der Abhängigkeitsklasse, um den Rückgabewert zu überprüfen)

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

Andere Tipps

Du könntest benutzen Mavenproject#getDependencyArtifacts () oder Mavenproject#getDependencies () (Der spätere kehrt auch transitive Abhängigkeiten zurück).

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

       ...
    }

}

Ich bin mir nicht ganz sicher, aber ich denke, beide Methoden geben eine Sammlung von zurück Artefakt Implementierungen, die Getter für GroupID, Artefactid, Version usw. enthüllen

Hier finden Sie ein aktuelles Beispiel für ein Beispiel dafür, wie alle Abhängigkeiten (einschließlich Transitive) erhalten und Zugriff auf die Dateien selbst erhalten können (wenn Sie zum Beispiel die Pfade zu einem Klassenpfad hinzufügen müssen).

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

Das Ändern der Parameter im Mojo ist ein sehr wichtiges Stück, das mir fehlte. Ohne sie wie Folgendes wie folgt:

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

Wird nur das Klassenverzeichnis zurückgeben, nicht den von Ihnen erwarteten Weg.

Wenn Sie die Anforderungen von Abhängigkeit ändern und die Abhängigkeit von Abhängigkeiten auf verschiedene Werte erfordern, können Sie den Umfang dessen ändern, was Sie greifen möchten. Das Maven -Dokumentation kann Details liefern.

Versuchen zu benutzen Aether Versorgungsklasse von JCABI-AETHER Um eine Liste aller Abhängigkeiten eines Artefakts zu erhalten:

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

Warum nicht einfach alle Abhängigkeiten (sowohl direkte als auch transitive) zurückbekommen und nach Ausschluss überprüfen?

@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 Verwenden Sie Aether, hier gibt es Beispiele:https://docs.sonatype.org/display/aether/home

Für Maven 3 können Sie Abhängigkeitsgraphbuilder verwenden. Es tut so ziemlich das Gleiche wie DependentyTreebuilder.

Hier ist das Beispiel

    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();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top