问题描述
我正在尝试创建一个简单的注释 (@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 (将#修改为@)