ceepan
ceepan

Reputation: 95

Can a Maven Plugin operate on JAR created as part of build

I want to create a Maven plugin that will only be run after a release build of my jar. The purpose is to identify all classes within my JAR that are annotated with a custom annotation. It will then call a REST API with the details of these classes.

I have been looking at using javaparser to scan the source. Is it possible to inspect the built jar file from a maven plugin. That way i could use the Reflections library (getTypesAnnotatedWith) and it would make the process a bit easier.

Edit I have tried using Aether but am running into problems

package mypackage.maven.plugins;

import java.net.MalformedURLException;
import java.util.Set;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.collection.DependencyCollectionException;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.reflections.Reflections;
import org.reflections.scanners.Scanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ConfigurationBuilder;

import my.package.annotations.MyAnnotation;

@Mojo(name = "identify-checks")
public class MyCheckMojo extends AbstractMojo
{
    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    MavenProject project;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException
    {                        
        RepositorySystem repoSystem = newRepositorySystem();

        RepositorySystemSession session = newSession( repoSystem );
        String coords = project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion();


        Dependency dependency = new Dependency( new DefaultArtifact(coords), "compile" );
        RemoteRepository central = new RemoteRepository.Builder( "central", "default", "http://myrepo:8081/nexus/content/repositories/" ).build();

        CollectRequest collectRequest = new CollectRequest();
        collectRequest.setRoot( dependency );
        collectRequest.addRepository( central );
        DependencyNode node;
        try
        {            
            node = repoSystem.collectDependencies( session, collectRequest ).getRoot();

            Artifact artifact = node.getArtifact();
            artifact.getArtifactId();

            ArtifactRequest artifactRequest = new ArtifactRequest();
            artifactRequest.setArtifact(artifact);
            ArtifactResult artifactResult = repoSystem.resolveArtifact(session, artifactRequest);
            artifact = artifactResult.getArtifact();

            ConfigurationBuilder configBuilder = new ConfigurationBuilder()
                    .addUrls(artifact.getFile().toURI().toURL())
                    .filterInputsBy(new FilterBuilder().include("my.package"))
                    .setScanners(new SubTypesScanner(false), new TypeAnnotationsScanner());

            Set<Scanner> scanners = configBuilder.getScanners();
            //SubTypesScanner = new SubTypesScanner(false);

            Reflections reflections = new Reflections(configBuilder);
                        //.setScanners(new SubTypesScanner(), new TypeAnnotationsScanner().filterResultsBy(myClassAnnotationsFilter)));
            Set<Class<?>> checks = reflections.getTypesAnnotatedWith(MyAnnotation.class, true);
            System.out.println("Number of checks is " + checks.size());
            for(Class<?> check : checks)
            {
                System.out.println(check.getName());
            }
            System.out.println("sdf");

        }
        catch (DependencyCollectionException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        catch (ArtifactResolutionException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (MalformedURLException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static RepositorySystem newRepositorySystem()
    {
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
        locator.addService( TransporterFactory.class, FileTransporterFactory.class );
        locator.addService( TransporterFactory.class, HttpTransporterFactory.class );

        return locator.getService( RepositorySystem.class );
    }

    private static RepositorySystemSession newSession( RepositorySystem system )
    {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();

        LocalRepository localRepo = new LocalRepository( "C://maven_repository//repository" );
        session.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );

        return session;
    }
}

Upvotes: 2

Views: 146

Answers (1)

Karol Dowbecki
Karol Dowbecki

Reputation: 44952

Yes, either by referencing the artifact location (usually denoted by ${project.build.directory}/${project.build.finalName} properties) or by using ArtifactResolver in the plugin. You can take look at Apache Tomcat Maven Plugin source code which looks the artifact up from both local or remote Maven repository.

Do note that you must bind your custom plugin after package phase, usually in the verify phase.

Upvotes: 1

Related Questions