Can I use compileOnly as a replacement for annotationProcessor in gradle?

假装没事ソ 提交于 2020-06-15 09:26:07

问题


My current understanding of annotation processor is that it refers to code that pre-parses a file looking for certain annotations, generating or changing other code based on that. It happens before the regular compilation phase of your project.

In gradle we typically use apt, kpt - and I've seen sometimes the use of annotationProcessor - to indicate that some dependency will be needed at "annotation processing time".

If the understand above is right, how does compileOnly differs from apt, kpt, etc?


回答1:


As you've said, there are couple of annotation processing solutions in Gradle:

  1. annotationProcessor facilities for Android
  2. apt for pure Java and Groovy
  3. kapt for Kotlin

and so on. You can even implement one yourself! All of them use separate configuration for annotation processing.

Some of them, indeed, used to use compile classpath for processing. But this is not semantically corrent, it is not a "Gradle way". You should not mix your compile time only dependencies with the artifacts, required for you app to run. One simple scenario I can think of is creating fat JARs: most probably you do not want to pack and ship the processors you've used because it makes no sense! There may be other scenarios as well.

What you can do, thanks to Gradle's flexibility, is create another classpath (configuration) and use it only for annotation processing and then just forget about them. It is kind of semantics: you're telling Gradle (and other developers) that these dependencies are not required for you application to run. And this is the place where compileOnly differs from apt: compileOnly dependencies are mandatory for you code to operate, but they are meant to be provided by the environment. Will it be your application server, or plugin host system, or even you'll add them to the classpath manually - they will just exist on you runtime so you should not pack them with your distributable. But they are required to for your code to run. Some examples of compileOnly dependencies are Servlet API (your classes obviously extend and use them, but it will be provided by the server) or, if you're writing a Jenkins plugin, Jenkins core APIs (your plugin will be installed in a Jenkins where that core already exists). JDK itself is kind of compileOnly too. Annotation processors, on the contrary, are not meant to be used at runtime at all. They won't exist on classpath and they are not needed to run your app: they already generated some code that was compiled later.

Other implication of "mixing" configuration is performance. Just let me quote Android's documentation:

In previous versions of the plugin, dependencies on the compile classpath were automatically added to the processor classpath. That is, you could add an annotation processor to the compile classpath and it would work as expected. However, this causes a significant impact to performance by adding a large number of unnecessary dependencies to the processor.



来源:https://stackoverflow.com/questions/47224294/can-i-use-compileonly-as-a-replacement-for-annotationprocessor-in-gradle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!