كيفية الوصول إلى التسلسل الهرمي للاعتماد على Maven ضمن البرنامج المساعد

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

سؤال

في البرنامج المساعد، أحتاج إلى معالجة التسلسل الهرمي التبعي والحصول على معلومات (GroupID، Artifactid، إصدار، إلخ) حول كل تبعية وإذا تم استبعادها. ما هي أفضل طريقة للقيام بذلك؟

هل كانت مفيدة؟

المحلول

البرنامج المساعد التبعية لديه هدف شجرة هذا يفعل معظم هذا العمل. يعالج A. MavenProject باستخدام DependencyTreeBuilder, هذا يعود DependencyNode مع معلومات هرمية حول التبعيات المعلمة (وتبعينها متعدية).

يمكنك نسخ الكثير من الكود مباشرة من Tremojo. يستخدم 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 # getdependations () (في وقت لاحق يعود المرء أيضا تبعيات متعدية).

/**
 * 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 for groupid، artifactid، الإصدار، إلخ.

فيما يلي مثال محدث، مثال Maven3 على كيفية الحصول على جميع التبعيات (بما في ذلك متعدية) بالإضافة إلى الوصول إلى الملفات نفسها (إذا كنت بحاجة إلى إضافة المسارات إلى 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.
    }
  }
}

تغيير المعلمات في Mojo هو قطعة مهمة للغاية كنت في عداد المفقودين. بدونها، خطوط مثل ما يلي:

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

سيعود فقط دليل الطبقات، وليس المسار الذي تتوقعه.

يتيح لك تغيير الحاجة إلى تغيير الزيادة والذي يتطلب الثور القيم المختلفة تغيير نطاق ما تريد الاستيلاء عليه. ال وثائق منافن يمكن أن توفر المزيد من التفاصيل.

حاول استخدام Aether فئة فائدة من JCABI الأليفة للحصول على قائمة بجميع التبعيات في أي قطعة أثرية:

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 استخدم الأثير، هناك عينة هنا:https://docs.sonatype.org/display/aether/home

بالنسبة إلى Maven 3، يمكنك استخدام decorencygraphbuilder. انها تفعل الكثير من نفس الشيء مثل dependencytreeBuilder.

هنا هو المثال

    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