[JAVA] Getting Started with Doma-Annotation Processing


Annotation processing (annotation processing) is the most distinctive feature of Doma and is also a demon.

The description is based on the latest Doma 2.44.1, but basically it applies to all versions.

Please also read Introduction to Doma for an introduction to other features of Doma.

What is annotation processing?

Annotation processing (https://jcp.org/en/jsr/detail?id=269) can be used to read the annotations given to the source code at compile time and generate another source code or bytecode. I will.

Doma is a type of framework that generates source code, for example Micronaut generates bytecode.

From the user's point of view, the type that generates source code has the advantage that it is easy to debug because it can read the code and set breakpoints, and the type that generates bytecode has the advantage that compile time can be skipped.

Benefits of annotation processing

I think there are three main advantages.

  1. Boilerplate code can be reduced
  2. Can detect errors at compile time
  3. Can speed up bootstrap (initialization) at runtime

Boilerplate code can be reduced

Boilerplate code reduction is not limited to annotation processing, but can also be achieved, for example, in reflection. In this regard, a product called AutoValue can be helpful in comparing annotation processing with other techniques. This slide is especially interesting.

Although not mentioned in the AutoValue slides, when it comes to reflection, the benefits of annotation processing are significant when considering native imaging. This is because you can avoid the reflection constraint when creating a native image.

Can detect errors at compile time

Regarding this point, [Reduce what you don't know if you don't move](https: //qiita.com/nakamura-to/items/099cf72f5465d0323521) //qiita.com/nakamura-to/items/099cf72f5465d0323521#1-Reduce what you don't know if you don't move).

Faster bootstrap at runtime

The reason why bootstrap at run time can be accelerated is that metadata that would otherwise be generated at run time and kept in memory can be generated as a class at compile time.

Hibernate is a typical DB access framework that takes a relatively long time to bootstrap. Hibernate reads the information of the entity class by reflection to create SessionFactory (EntityManagerFactory when used as JPA) and performs various processing. If you have a small number of entity classes, you probably won't mind it at all, but if you have a large number, you'll notice that it takes significantly longer to initialize. If you set the log level to trace etc., you can see what you are doing.

In Quarkus Hibernate Extension, I made about 100 entities and ran the sample, thinking that there might be countermeasures around that, but dozens by the time it starts. It took a second, so I didn't seem to have any countermeasures (I tried it in JVM mode, but it may be different in Native mode).

With Doma, on the other hand, you can get the metadata you need by simply loading a class that already exists at runtime. What's more, the bootstrap time doesn't increase as the number of entity classes increases because the classes are loaded as needed instead of being loaded all at once during bootstrap.

Things to watch out for in annotation processing

The most important thing to note is that the IDE requires special settings to enable annotation processing. Also, what you need to be aware of depends on whether you use Maven or Gradle as the build tool.

I wrote "Kimon" at the beginning, but most of the phenomenon that Doma does not work seems to be related to this setting.

Recommended IDE and build tools

In the IDE, we have confirmed the operation with both Eclipse and IntelliJ IEDA. I'm completely fond of which one is better, but Eclipse often has to be more careful to get the annotation process working. However, it's not a big deal if you get the hang of it, and since the execution of annotation processing by incremental compilation of Eclipse is quicker feedback than when using IDEA, Eclipse is used just because there are many points to be aware of. I think it's regrettable to truncate (in IDEA, annotation processing doesn't work unless you build it explicitly, but in Eclipse, it works every time you save a file, and errors due to annotation processing are quickly fed back to the developer ).

The build tool has been confirmed to work with Gradle and Maven. You can use either of these as you like, but I personally have little know-how about the combination of Eclipse and Maven. It seems that I am often addicted to the behavior of M2 Eclipse. However, I know that the cause is around the SQL file, so if you only use the Criteira API, you may not be so troubled.

It is possible to run it in Eclipse or IEDA without using Gradle or Maven, but I don't recommend it at all </ font>. I'm absolutely addicted to various settings including dependent libraries, so I definitely want you to use either Gradle or Maven.

In summary, it looks like this.

IDE Build tool Explanation
Eclipse Gradle It will be described later.
Eclipse Maven Lack of know-how. Not mentioned in this article. Looking for information.
IDEA Gradle You can import it as a Gradle project.
IDEA Maven You can import it as a Maven project.

Points when combining Eclipse and Gradle

First, create a project in Gradle. It's important to run it as a Gradle project first, not Eclipse. We recommend using the following project as a template.

  • https://github.com/domaframework/getting-started

This project has a Gradle multi-project structure. If what you want to create doesn't require a multi-project configuration, you can keep this multi-project configuration. Also, although this project is made with Kotlin DSL, I think that it is okay to continue using Kotlin DSL as it is (do not rewrite with Groovy DSL) considering the ease of refactoring as well. In addition, this project uses the Gradle Wrapper, and I don't think there's any reason not to use it either.

The most important thing in a Gradle project is to use a Gradle plugin called com.diffplug.eclipse.apt. This plugin outputs the settings for running annotation processing in Eclipse. This plugin hooks your Gradle eclipse project, so you can run ./gradlew eclipse to output the required config files. Just in case, always with the cleanEclipse task It is recommended to use ./gradlew cleanEclipse eclipse.

Import the project into Eclipse only after outputting the above configuration file. Since Eclipse does not recognize Gradle's multi-project, only child projects are imported into Eclipse in the case using the above template, but I recognize that it does not matter.

In the process of development, it may be necessary to upgrade the version of the dependent library or change the annotation processing settings. In that case, instead of modifying it from Eclipse, first modify the Gradle build script. After that, execute ./gradlew cleanEclipse eclipse to re-output the Eclipse configuration file and refresh the Eclipse project (reload the configuration file). It's very important that the Gradle build script is always positive </ font>.

in conclusion

I explained the annotation processing of Doma.

Recently, I opened a room dedicated to Doma in a chat service called Zulip. If you have any questions about Doma, feel free to use this chat room.

  • https://domaframework.zulipchat.com/

For example, how to write annotation processing settings in Gradle's build script may be a problem because there is little information in the world, but if you ask a question, I can give you advice.

Of course, we also welcome the participation of those who can cooperate in the development of Doma and related products of Doma and those who can share information.

Recommended Posts