Skip to content
Advertisement

Compile-time annotation processing

Is there way to do compile-time annotation processing in Java?

Consider this example:

@Name("appName")
private Field<String> appName;

public void setAppName(String name) {
   appName.setValue(name);
}

public String getAppName(String name) {
   return appName.getValue();
}

public void someFunction() {
   String whatFieldName = appName.getName();
}

Where the annotation Name will be processed at compile-time to set the value for Field That is without the common runtime annotation processing. As such, when appName.getName(); (the Field) is accessed it will return the typed value.

Advertisement

Answer

Yes, there is, but, no, it cannot change existing files. You can ‘plug in’ to the compiler and be informed of any annotations; as part of this, you can see signatures (so, field declarations, method signatures, types, etc) but no contents (so not the expression used to initialize a field, and not the contents in the {} of a method declaration), and you can make NEW files, even java files, but you can’t edit existing ones.

Project Lombok does edit them, but that is quite the framework to make that possible.

There are some crazy tricks you can use. Project lombok uses one trick (reflect its way into compiler internals, fix everything from there, install agents and plugins in IDEs). Another trick is to use a java source file as a template, of sorts. You name your class some funky (so if you want, say, public class AppDescriptor, you’d actually make the java file AppDescriptorTemplate.java and put public class AppDescriptorTemplate inside. This file has the annotation precisely as you pasted. Your annotation processor can then, during compilation, generate AppDescriptor.java, writing the impls of all methods as simple pass-throughs (a field of type AppDescriptorTemplate is generated, and all methods in ADT are copied over, and the implementations are all one-liners that just invoke that method on the template class). The template class can be package private. In this specific scenario it sounds like you can generate virtually the whole thing based off of pretty much only "appName", though.

Lombok plugs straight into the build and is therefore virtually entirely transparent, in the sense that you simply type in your IDE and the methods it generates just appear as you type, whereas ‘normal’ annotation processors that e.g. use the XTemplate trick do not work that way and require the build system to kick in, every time. It can be a bit of a productivity drain.

Advertisement