1. 首页 > 快讯

AnnotationProcessor 处理器问题怎么深度定位?-51CTO.COM

各位老铁们好,相信很多人对AnnotationProcessor 处理器问题怎么深度定位?-51CTO.COM都不是特别的了解,因此呢,今天就来为大家分享下关于AnnotationProcessor 处理器问题怎么深度定位?-51CTO.COM以及的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

编写过自定义注释处理器的老司机乍一看认为这个问题相当简单。是的,因为基本上网上所有的文章都是教你如何日志的,但是你有没有想过如果你连日志都打印不出来会发生什么?你如何定位它?例如,以下代码:

//确认META-INF/services/javax.annotation.processing.Processor没问题//确认构建脚本没问题,确认使用了注解Bridge并参与构建@AutoService(Processor.class)publicclassTestAnnotationProcessorextendsAbstractProcessor{ publicTestAnnotationProcessor(){System .out.println('TestAnnotationProcessorconstrator');}@Overridepublicsynchronizedvoidinit(ProcessingEnvironmentprocessingEnvironment){super.init(processingEnvironment);System.out.println('TestAnnotationProcessorinit');}@OverridepublicSetStringgetSupportedAnnotationTypes(){System.out. println('TestAnnot ationProcessorgetSupportedAnnotationTypes' );SetStringsupported=newHashSetString();supported.add(Bridge.class.getCanonicalName());returnsupported;}@Overridepublicbooleanprocess(Set?extendsTypeElementset,RoundEnvironmentroundEnvironment){System.out.println('TestAnnotationProcessorprocess') ;returntrue;}}运行构建后,compileReleaseJavaWithJavac进程没有先吐出我的注释处理器的任何一行日志,直接报错找不到我的注释处理器的产品类引用(即直接执行编译类链接)。

你很困惑吗?反正我很困惑!打印日志不好用,哈哈,环境确认没问题,搞什么,直接绕过Annotation Processor编译。

这时候就需要做一点深入的定位分析(熟悉javac源码的请自行通过)。前提是你需要熟悉Annotation Processor的基本原理,然后我们会使用一些额外的javac详细日志进行示例分析。

Annotation Processor 机制注解和注解处理器是JDK5中引入的机制,主要用于为类、方法、字段、参数等Java结构提供附加信息。比如常见的@Override就是一个只在Java编译器上生效的注解。 Java允许我们自定义注解。自定义注解处理器就是用来处理这些自定义注解的(废话)。注解处理器的触发时机是由javac来处理的,所以整个javac流程的简要步骤如下:

javac主要步骤

可以看到,javac编译总结图主要分为以下几个步骤:

将源文件解析为抽象语法树。调用已注册的注释处理器。如果注释处理器在处理过程中生成新的源文件,则编译器重复步骤1和2。当注释处理器不再生成新的源文件时,则进入最后一轮。输入真正的编译字节码链接,生成字节码。以上就是注解处理器的核心机制。了解了这个核心机制后,我们将继续探索。

构建工具下 Annotation Processor 的本质增强 javac 过程打印暴露问题为了解决开头提到的Annotation Processor中自己添加的日志不打印场景的问题,我们需要获取一些额外的信息来辅助定位。由于直接使用命令行javac是最原始的操作,所以我们一般使用Gradle进行构建,而Gradle的本质就是调用javac,所以下面我们以Gradle为例来分析一下如何定位Annotation Processor问题。

最简单粗暴的一点就是直接在根目录下的build.gradle中给所有模块添加参数:

//参数可选,重点是-verbose-XprintRounds-XprintProcessorInfoallprojects{gradle.projectsEvaluated{tasks.withType(JavaCompile){options.compilerArgs'-Xlint''-verbose''-XprintRounds''-XprintProcessorInfo''-Xmaxerrs' ' 100000'}}} 您也可以将其添加到具有注释处理器的模块中。如上,只需将其添加到JavaCompile的参数中即可。这里的参数其实就是我们平时命令行javac的参数。如果不明白,可以到命令行执行javac -help来了解含义,如下(JDK8,不同版本的JDK略有差异):

yan@yanDeMackbookPro:~$javac-help 用法:javacoptionssourcefiles 其中,可能的选项包括: -g 生成所有调试信息. -有关编译器正在执行的操作的详细输出消息. -processorclass1[ , class2, class3.]要运行的注释处理程序的名称;绕过默认的搜索过程-processorpath 路径指定在哪里找到注释处理程序.至于脚本中的其他几个,它们在javac -help 中,如果没有参数,可以阅读官方文档https://docs.oracle.com/en /java/javase/11/tools/javac.html,里面详细解释了参数的含义。

添加以上参数后,一定要将你的构建日志追加到磁盘文件中,因为日志会变得非常大,同时也会变得很容易定位问题。

通过构建日志分析定位问题执行您的施工任务。完成后,分析定位主要分为以下几个步骤。每一步都是一个场景的定位。您可以逐步定位和分析。

1. 在日志中搜索您的Processor 类名,例如TestAnnotationProcessor.class,您看到的日志将如下所示。

//如果你的注解处理器是项目中源代码形式的日志[loadingRegularFileObject[/home/user/yan/test/target/classes/cn/yan/test/TestAnnotationProcessor.class]]//如果你的注解处理器项目中的处理器依赖于jar形式的日志[loadingZipFileIndexFileObject[./test.jar(cn/yan/test/TestAnnotationProcessor.class)]] 2. 在日志中搜索Round 关键字。建议直接搜索Round 1: 这样的格式比较容易,看到的日志会如下。

Round1:inputfiles:{cn.yan.test.Application,cn.yan.test.UseMarkedAnnotation}annotations:[java.lang.Override,cn.yan.annotation.Bridge]lastround:false 分析:如果没有搜索到你的日志如果你到达了上面的回合,说明javac 没有触发对任何注解处理器的调用(无论是你自己写的还是依赖第三方框架)。最大的可疑点是检查你是否禁用了javac注释处理器,即确认执行javac时。没有-proc:none 参数。如果你的日志中有Round,但是输入files:和annotations:没有你的注解类和用法类,则说明你的代码中还没有使用你的注解处理器想要处理的注解。

3、在日志中搜索Loaded cn.yan.test.TestAnnotationProcessor关键字,看到的日志如下。

[Loadedcn.yan.test.TestAnnotationProcessorfromfile:/home/user/yan/test/target/classes/cn/yan/test/TestAnnotationProcessor.class] 分析:如果看不到上面这行日志,说明你的注解处理器类是这样的没有加载成功。不知道怎么分析为什么没有加载,但是至少说明没有加载成功。您可能需要仔细检查是什么违规或违法行为造成的。

这个技能有什么鸟用?说实话,我是个老司机了。 6年前我就一直在玩Annotation Processor。但是,项目最近升级构建并支持Java8和androidX后,我合并了代码,然后项目中的注释处理器,dataBinding都停止工作了。更可气的是,这实在不行的时候就太抠门了。没有错误堆栈。奇怪的构建日志大致如下:

FAILURE:Buildfailedwithanexception.*Whatwentwong:Executionfailedfortask':test:test:compileReleaseJavaWithJavac'.//本来应该先吐出注解处理器内部的日志,然后继续javac编译,但实际上什么也没吐出来编译失败;请参阅编译器错误输出了解详细信息。*Exceptionis:org.grad le.api.tasks.TaskExecutionException:Executionfailedfortask':moffice:compileReleaseJavaWithJavac '.aorg.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:200).Causedby:org.gradle.api.internal.tasks.compile.CompilationFailedException:Compilationfailed;seethecompilererrorout putfordetails.aorg.gradle .api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:57) Gradle构建命令添加了各种详细参数用于查看堆栈和详细日志,但奇妙的是,当它到compileReleaseJavaWithJavac时,直接出现错误。没有之前或之后。任何错误消息(有些只是Gradle 自己的任务调用链的一堆)。我太粗心了。我同步了代码。如果我不能编译它,我就不能。你应该提醒我这个问题!我直接进入编译类链接,没有任何提示,并跳过了注释处理器过程。这很烦人。还好我按照上面的方法修复了,哈哈。

好了,文章到这里就结束啦,如果本次分享的AnnotationProcessor 处理器问题怎么深度定位?-51CTO.COM和问题对您有所帮助,还望关注下本站哦!

用户评论

开心的笨小孩

AnnotationProcessor 我一直遇到问题,这篇博客好像能帮的上忙啊!

    有18位网友表示赞同!

有阳光还感觉冷

想深入了解AnnotationProcessor原理,这篇文章看起来很专业。

    有15位网友表示赞同!

小清晰的声音

平时开发中碰到AnnotationProcessor 的问题还挺多,这篇文档希望能解决我的疑问。

    有9位网友表示赞同!

空谷幽兰

深度定位?这个词好霸气啊,看来可以学到真本事了!

    有18位网友表示赞同!

青衫故人

终于找到了相关的技术文章,马上收藏起来!

    有10位网友表示赞同!

一生荒唐

51CTO的文章质量一直不错,这篇文章应该能提供有用的信息。

    有16位网友表示赞同!

■□丶一切都无所谓

最近一直在研究AnnotationProcessor,希望能找到一些解决问题的思路。

    有7位网友表示赞同!

南宫沐风

需要学习一下 AnnotationProcessor 的处理机制,这次可以好好看看这篇文档了。

    有6位网友表示赞同!

肆忌

希望文章能够详细介绍常见问题及解决方案

    有9位网友表示赞同!

景忧丶枫涩帘淞幕雨

开发过程中遇到的Bug很多和AnnotationProcessor有关,希望这篇文章能提供一些帮助

    有15位网友表示赞同!

熟悉看不清

对于编程小白来说,深入定位 AnnotationProcessor 听起来有点难度啊!

    有16位网友表示赞同!

几妆痕

想要解决这个问题需要深入掌握其原理,看来这段时间要好好学习了。

    有20位网友表示赞同!

顶个蘑菇闯天下i

看了标题感觉很有深度,估计会介绍很多技术细节。

    有9位网友表示赞同!

凉城°

对AnnotationProcessor机制的理解不太够深,这篇文档希望能有所帮助

    有9位网友表示赞同!

初阳

在实际开发中 AnnotationProcessor 的问题确实常见,希望这篇文章能提供一些有效的解决方案。

    有8位网友表示赞同!

长裙绿衣

期待文章能够分享一些实际案例和经验教训

    有8位网友表示赞同!

服从

学习一下AnnotationProcessor的用法,也许可以提高效率。

    有16位网友表示赞同!

水波映月

这个博客的标题很有吸引力,我得去看看它的内容!

    有17位网友表示赞同!

丢了爱情i

想提升我的开发能力,需要进一步了解 AnnotationProcessor。

    有14位网友表示赞同!

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/7185.html

联系我们

在线咨询:点击这里给我发消息

微信号:666666