Sitemap

Annotation Processor Elements for Records

3 min readFeb 20, 2026

--

I found a use for a new annotation processor recently and I found Hannes Dorfmann’s page here really helpful to get started with writing them, particularly the commented class code example under “Elements and TypeMirrors”. I was also looking for an opportunity to paraphrase a particular song, and this seemed like it..

Little byte shadows sparkle and glisten .. part of a system, a plan .. Maybe you got what you wanted, maybe you stumbled upon it, everything you ever wanted — in a PermGen space :)

Anyway, Hannes Dorfmann’s page covered classes, not records, which I wanted an annotation processor for, so there was a bit for me to figure out myself. And in a similar style to his example, I can add that for a record the “precompilation metadata” we have available before we have a compiled class for reflection is like:

public record MyRecord( // TypeElement, kind=RECORD
String field1, // RecordComponentElement, kind=RECORD_COMPONENT
Instant field2 // RecordComponentElement, kind=RECORD_COMPONENT
) {
/* //The fields do not exist as such in the source code,
* //but the compiler will emit the following elements for the annotation processing:
*
* private final String field1; //VariableElement, kind=FIELD
* private final Instant field2; //VariableElement, kind=FIELD
*
*
*
* //Similarly for the constructor:
*
* public MyRecord( //ExecutableElement, kind=CONSTRUCTOR
* String field1, //VariableElement, kind=PARAMETER
* String field2 //VariableElement, kind=PARAMETER
* ) {
* ...
* }
*
* //And any constructors you might have added.
*
*
*
* //And getters - without the get Prefix - yay :)
*
* public String field1() { // ExecutableElement, kind=METHOD
* return field1;
* }
*
* public Instant field2() { // ExecutableElement, kind=METHOD
* return field2;
* }
*
* //And any methods you might have added, such as equals, hashcode, ..
*/
}

For a start, and in annotation processor code we can go through these like this:

@SupportedAnnotationTypes("com.my.package.MyAnnotation")
@SupportedSourceVersion(RELEASE_21)
@AutoService(javax.annotation.processing.Processor.class)
public class MyAnnotationProcessor extends AbstractProcessor {

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
for (Element element : roundEnvironment.getElementsAnnotatedWith(OurNewAnnotation.class)) {
MyAnnotation annotation = element.getAnnotation(MyAnnotation.class);
//We can use the above reference to the annotation to obtain field values from it.
if (element.getKind() == RECORD) {
for (Element enclosed : element.getEnclosedElements()) {
if (enclosed instanceof RecordComponentElement rcElement) {
//...

The second part is how to plug that into the compilation.

How to configure the build

The module with the annotation is a dependency of the module with the annotation processor which is a dependency of the module(s) where it is used. The split dependencies is to avoid including the processor code itself beyond compile time (see pom.xml build files below).

Get NSA’s stories in your inbox

Join Medium for free to get updates from this writer.

Using maven, to me the easiest was to use another annotation processor, Google’s AutoService. So the annotation processor class itself would be annotated with

@AutoService(javax.annotation.processing.Processor.class)

In short this adds the class name of the annotation processor to the file resources/META-INF/javax.annotation.processing.Processor.

pom.xml details for annotation processor module

...
<artifactId>the-annotation-processor-module</artifactId>
<groupId>...</groupId>
<version>...<version>

<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>the-annotation-module</artifactId>
...
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service-annotations</artifactId>
<version>1.1.1<version>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
...
</plugin>
</plugins>
</build>

pom.xml details for module using annotation processor

...
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>the-annotation-module</artifactId>
...
</dependency>
<dependency>
<artifactId>the-annotation-processor-module</artifactId>
<groupId>...</groupId>
...
<scope>compile</scope>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
...
<configuration>
<annotationProcessorPaths>
<path>
<groupId>...</groupId>
<artifactId>the-annotation-processor-module</artifactId>
<version>...</version>
</path>
</annotationProcessorPaths>
<annotationProcessors>
<proc>com.my.package.MyAnnotationProcessor</proc>
</annotationProcessors>
</configuration>
</plugin>
</plugins>
</build>

In case anyone finds it useful.

--

--

NSA
NSA

Written by NSA

Scientist turned software engineer. Into outdoors, exercise, photos, music & translation. Next spare time project - if I get such a thing: Shader raymarching.