Reputation: 95
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
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