Reputation: 2124
Currently I create a plugin that when executed need to be access the classes from project artifacts and retrieve the annotation.
/**
* Generate document for services
*
* @author Ali Irawan
*
* @goal doc
* @requiresDependencyResolution compile
* @phase generate-sources
*/
public class GeneratePlugin extends AbstractMojo {
/**
* project
*
* @parameter expression = "${project}";
*/
protected MavenProject project;
/**
* scanPackage
*
* @parameter
*/
private String scanPackage;
@Override
public void execute() throws MojoExecutionException {
getLog().info("My Maven Plugin Started");
getLog().info("Scanning package: " + scanPackage);
// PluginDescriptor pluginDescriptor = (PluginDescriptor) super.getPluginContext().get("pluginDescriptor");
try {
ClassLoader original = Thread.currentThread().getContextClassLoader();
Collection urls = new ArrayList();
Set<Artifact> artifacts = project.getArtifacts();
Iterator<Artifact> iterator = artifacts.iterator();
while(iterator.hasNext()){
Artifact entry = iterator.next();
urls.add(entry.getFile().toURI().toURL());
}
urls.add(new File(project.getBuild().getOutputDirectory()).toURI().toURL());
Thread.currentThread().setContextClassLoader(new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]),original));
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.goijo.mona.services.AuthenticationService");
getLog().info("Class name: " + clazz.getName());
// This always return 0, don't know why ?
getLog().info("Annotation : " + clazz.newInstance().getClass().getAnnotations().length);
// Restore class loader
Thread.currentThread().setContextClassLoader(original);
getLog().info("MyMaven Plugin Stopped");
} catch (Exception e) {
e.printStackTrace();
getLog().error(e.getMessage());
}
}
}
Then I use this plugin in other project
<plugin>
<groupId>com.my</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<configuration>
<scanPackage>com.my.services</scanPackage>
</configuration>
</plugin>
When I try to execute the mvn goals using
mvn my:doc
It produce this output
[INFO] Scanning package: com.goijo.mona.services
[INFO] Class name: com.my.services.AuthenticationService
[INFO] Annotation : 0
Any one can help why the annotation is always 0 As my class com.my.services.AuthenticationService is already annotated
@InfoIn( ... )
public class AuthenticationService {
}
And the annotation is already set the RetentionPolicy
@Target(value=ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InfoIn {
public Info[] value();
}
Upvotes: 4
Views: 2962
Reputation: 144
The root of your problem is with the ClassLoader you are using when loading external class files. The following code should get you passed your problem...I have written a similar maven plugin:
// The outputDirectory is the ${project.build.directory} the Maven plugin is executing in
File classesDirectory = new File(outputDirectory.getAbsolutePath() + "/classes");
URL classesUrl = classesDirectory.toURI().toURL();
URL[] classesUrls = new URL[]{classesUrl};
// Make sure to use the URLClassLoader, using the simple ClassLoader WILL NOT WORK for reading the annotations
URLClassLoader classLoader = URLClassLoader.newInstance(classesUrls, getClass().getClassLoader());
// Load our remote class file found out in the "/classes" directory
Class classObject = classLoader.loadClass("com.my.services.AuthenticationService");
// Check to make sure the class has the annotation
if(classObject.isAnnotationPresent(InfoIn.class))
{
// Get the annotation and print the value
InfoIn annotation = (InfoIn)classObject.getAnnotation(InfoIn.class);
System.out.println("Annotation value is: " + annotation.value());
}
I hope that helps.
Upvotes: 1