Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven Plugin API: Get MavenProject from Artifact

I am trying to extract information on all dependencies (recursively) used in my project. It seems like the MavenProject class provides all information that I require. But I can't figure out how to transform an instance of Artifact into an instance of MavenProject

/**
 * 
 *
 * @reqiresDependencyResolution
 *
 */
@Mojo(name = "license-overview", defaultPhase = LifecyclePhase.PROCESS_SOURCES)
public class MyMojo extends AbstractMojo {


    /**
     * @parameter default-value="${project}"
     * @required
     * @readonly
     */
    MavenProject project;


    public void execute() throws MojoExecutionException {

        Set<Artifact> artifacts= project.getArtifacts();
        for (Artifact artifact : artifacts) {
            //Here I need to access the artifact's name, license, author, etc.
            System.out.println("*** "+artifact.getArtifactId()+"***");
        }

    }
}

How to access the information that is located within the pom of my dependency, but is not exported via the Artifacts getters?

like image 512
gorootde Avatar asked Feb 17 '16 12:02

gorootde


1 Answers

Yes, this is possible.

We can build a project in-memory with the ProjectBuilder API:

Builds in-memory descriptions of projects.

By invoking the build(projectArtifact, request) method with the artifact we're interested in and a ProjectBuildingRequest (that holds various parameters like location of the remote / local repositories, etc.), this will build a MavenProject in-memory.

Consider the following MOJO that will print the name of all the dependencies:

@Mojo(name = "foo", requiresDependencyResolution = ResolutionScope.RUNTIME)
public class MyMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject project;

    @Parameter(defaultValue = "${session}", readonly = true, required = true)
    private MavenSession session;

    @Component
    private ProjectBuilder projectBuilder;

    public void execute() throws MojoExecutionException, MojoFailureException {
        ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
        try {
            for (Artifact artifact : project.getArtifacts()) {
                buildingRequest.setProject(null);
                MavenProject mavenProject = projectBuilder.build(artifact, buildingRequest).getProject();
                System.out.println(mavenProject.getName());
            }
        } catch (ProjectBuildingException e) {
            throw new MojoExecutionException("Error while building project", e);
        }
    }

}

There are a couple of main ingredients here:

  • The requiresDependencyResolution tells Maven that we require the dependencies to be resolved before execution. In this case, I specified it to RUNTIME so that all compile and runtime dependencies are resolved. You can of course set that to the ResolutionScope. you want.
  • The project builder is injected with the @Component annotation.
  • A default building request is build with the parameter of the current Maven session. We just need to override the current project by explicitly setting it to null, otherwise nothing will happen.

When you have access to the MavenProject, you can then print all the information you want about it, like developers, etc.

If you want to print the dependencies (direct and transitive), you will also need to invoke setResolveDependencies(true) on the building request, otherwise, they won't be populated in the built project.

like image 89
Tunaki Avatar answered Nov 09 '22 09:11

Tunaki