各位老铁们好,相信很多人对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和问题对您有所帮助,还望关注下本站哦!
本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/7185.html
用户评论
AnnotationProcessor 我一直遇到问题,这篇博客好像能帮的上忙啊!
有18位网友表示赞同!
想深入了解AnnotationProcessor原理,这篇文章看起来很专业。
有15位网友表示赞同!
平时开发中碰到AnnotationProcessor 的问题还挺多,这篇文档希望能解决我的疑问。
有9位网友表示赞同!
深度定位?这个词好霸气啊,看来可以学到真本事了!
有18位网友表示赞同!
终于找到了相关的技术文章,马上收藏起来!
有10位网友表示赞同!
51CTO的文章质量一直不错,这篇文章应该能提供有用的信息。
有16位网友表示赞同!
最近一直在研究AnnotationProcessor,希望能找到一些解决问题的思路。
有7位网友表示赞同!
需要学习一下 AnnotationProcessor 的处理机制,这次可以好好看看这篇文档了。
有6位网友表示赞同!
希望文章能够详细介绍常见问题及解决方案
有9位网友表示赞同!
开发过程中遇到的Bug很多和AnnotationProcessor有关,希望这篇文章能提供一些帮助
有15位网友表示赞同!
对于编程小白来说,深入定位 AnnotationProcessor 听起来有点难度啊!
有16位网友表示赞同!
想要解决这个问题需要深入掌握其原理,看来这段时间要好好学习了。
有20位网友表示赞同!
看了标题感觉很有深度,估计会介绍很多技术细节。
有9位网友表示赞同!
对AnnotationProcessor机制的理解不太够深,这篇文档希望能有所帮助
有9位网友表示赞同!
在实际开发中 AnnotationProcessor 的问题确实常见,希望这篇文章能提供一些有效的解决方案。
有8位网友表示赞同!
期待文章能够分享一些实际案例和经验教训
有8位网友表示赞同!
学习一下AnnotationProcessor的用法,也许可以提高效率。
有16位网友表示赞同!
这个博客的标题很有吸引力,我得去看看它的内容!
有17位网友表示赞同!
想提升我的开发能力,需要进一步了解 AnnotationProcessor。
有14位网友表示赞同!