java - 在 Maven 插件中访问注解

标签 java maven plugins annotations

目前我创建了一个插件,在执行时需要从项目 Artifact 访问类并检索注释。

/**
 * 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());
        }
    }


}

然后我在其他项目中使用这个插件
<plugin>
    <groupId>com.my</groupId>
    <artifactId>my-maven-plugin</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <configuration>
        <scanPackage>com.my.services</scanPackage>
    </configuration>
</plugin>

当我尝试使用执行 mvn 目标时
mvn my:doc

它产生这个输出
[INFO] Scanning package: com.goijo.mona.services
[INFO] Class name: com.my.services.AuthenticationService
[INFO] Annotation : 0

任何人都可以帮助解释为什么注释总是 0
因为我的类(class) com.my.services.AuthenticationService 已经被注释了
@InfoIn( ... )
public class AuthenticationService {

}

并且注释已经设置了 RetentionPolicy
@Target(value=ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InfoIn {

    public Info[] value();

}

最佳答案

问题的根源在于您在加载外部类文件时使用的 ClassLoader。下面的代码应该让你通过你的问题......我写了一个类似的 maven 插件:

// 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());
}

我希望这有帮助。

关于java - 在 Maven 插件中访问注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11219677/

相关文章:

jakarta-ee - 带有 main() 的 EJB - 这是怎么回事?

grails - 更改Grails插件的默认位置

eclipse - 禁用 Saros 欢迎页面

java - 应用程序中的 Android Wear 手势(版本 1.4),不仅仅用于通知?

java - Netbeans 中的 .dat 文件未打包为 jar

java - 如何在 Java 中测试缓冲图像的像素的某种颜色

java - 无法执行目标 org.apache.maven.plugins :maven-jar-plugin:2. 6:jar

php - WooCommerce Wordpress 插件问题

java - Java 字符串上 + 和 += 的区别

java - 在Java中的foreach循环中调用remove