微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

注释处理在普通 Java 15 中不起作用

如何解决注释处理在普通 Java 15 中不起作用

我正在尝试创建一个简单的注释 (@NewIntent),用它注释的类应该在控制台上打印 hello world。 我想要实现的是用一些东西注释一个类,并能够收集该类的 javadoc 并在以后打印它(类似于列出所有命令的帮助函数)。

作为朝着这个目标迈出的一小步,我正在尝试创建自定义注释:D 但是,我不断收到以下异常:

org.gradle.api.GradleScriptException: A problem occurred evaluating root project 'AnnotationsTesting'.
    Caused by: groovy.lang.MissingPropertyException: Could not get unkNown property 'custom' for task ':myCustomAnnotationProcessorTask' of type org.gradle.api.tasks.compile.JavaCompile.
    at org.gradle.internal.Metaobject.AbstractDynamicObject.getMissingProperty(AbstractDynamicObject.java:85)
    at org.gradle.internal.Metaobject.ConfigureDelegate.getProperty(ConfigureDelegate.java:130)
    at build_4bjccfv4xujp6uu49zc54jj7x$_run_closure4.doCall(C:\Users\k\IdeaProjects\AnnotationsTesting\build.gradle:25)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    at 
    ... 140 more

我正在关注这个 tutorial,但正如你所看到的,它是基于 android 的,这应该不是问题,但我想要一些纯 Java 的东西,只是为了了解它并使用它在后来的项目中,但几乎没有解释这一点的 java gradle 教程(我发现的唯一一个this one,但它侧重于映射,这不是我需要的)。

我的项目结构如下:

AnnotationsTesting
|-> custom-annotation
|-> custom-processor
|-> src.main.java.Main

其中 custom-annotation 和 custom-processor 是其他具有自己 build.gradle 的模块:

这些是自定义处理器的依赖项:

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'

    compile group: 'com.google.guava',name: 'guava',version: '30.1-jre'
    compile group: 'com.squareup',name: 'javapoet',version: '1.13.0'
    compile group: 'org.kohsuke.Metainf-services',name: 'Metainf-services',version: '1.8'
    compile project(':custom-annotation')
}

我使用 JavaPoet 生成 java 文件并使用 org.kohsuke.Metainf-services 生成 meta-inf,因为我没有足够的信心自己做(而且我也不确定这是否被认为是一种好的做法) )


以下是 AnnotationsTesting 项目本身的依赖项:


dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'

    compile project(':custom-annotation')
    annotationProcessor project(':custom-processor')
}

task myCustomAnnotationProcessorTask(type: JavaCompile,group: 'build') {
    source = custom-processor.main.java
    classpath = custom-processor.main.compileClasspath
    options.compilerArgs = ['-proc:only','-processor','javacore.processors.Processor']
}
compileJava.dependsOn myCustomAnnotationProcessorTask

这里的任务来自另一个 SO question。我知道它试图告诉编译器将我的 NewIntentProcessor 识别为处理器,但似乎出了点问题。


最后,这是我的 NewIntenProcessor.java:

import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.typespec;
import org.kohsuke.MetaInfServices;

import javax.annotation.processing.*;
import javax.lang.model.sourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@MetaInfServices
public class NewIntentProcessor extends AbstractProcessor {

    private Filer filer;
    private Messager messager;
    private Elements elements;
    private Map<String,String> activitiesWithPackage;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        filer = processingEnvironment.getFiler();
        messager = processingEnvironment.getMessager();
        elements = processingEnvironment.getElementUtils();
        activitiesWithPackage = new HashMap<>();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set,RoundEnvironment roundEnvironment) {

        try {
            /**
             * 1- Find all annotated element
             */
            for (Element element : roundEnvironment.getElementsAnnotatedWith(NewIntent.class)) {

                if (element.getKind() != ElementKind.CLASS) {
                    messager.printMessage(Diagnostic.Kind.ERROR,"Can be applied to class.");
                    return true;
                }

                TypeElement typeElement = (TypeElement) element;
                activitiesWithPackage.put(
                        typeElement.getSimpleName().toString(),elements.getPackageOf(typeElement).getQualifiedname().toString());
            }


            /**
             * 2- Generate a class
             */
            MethodSpec main = MethodSpec.methodBuilder("main")
                    .addModifiers(Modifier.PUBLIC,Modifier.STATIC)
                    .returns(void.class)
                    .addParameter(String[].class,"args")
                    .addStatement("$T.out.println($S)",System.class,"Hello,JavaPoet!")
                    .build();

            typespec.Builder helloWorld = typespec
                    .classBuilder("HelloWorld")
                    .addModifiers(Modifier.PUBLIC,Modifier.FINAL)
                    .addMethod(main);

            JavaFile javaFile = JavaFile.builder("com.example.helloworld",helloWorld.build())
                    .build();

            javaFile.writeto(filer);


            /**
             * 3- Write generated class to a file
             */
            JavaFile.builder("com.annotationsample",helloWorld.build()).build().writeto(filer);


        } catch (IOException e) {
            e.printstacktrace();
        }

        return true;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return ImmutableSet.of(NewIntent.class.getCanonicalName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}


我正在使用最新版本的 IntelliJ IDEA 来开发这个项目 我期待代码改进建议/其他想法以及社区的帮助:D

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。