Post on 25-Jan-2017
Annotation processor and compiler plugin as code generators.
Hello!I am Oleksandr Radchykov
committed.chinchilla@gmail.combelict
Agenda
1.Motivation2.How to generate code?3.How to annotation processor4.How to create plugin5.Demo
Motivation for code generation
Getting rid of boilerplateclass MyService { private final String name; private final Integer version;
public MyService(String name, Integer version) { this.name = name; This.version = version; }
public String getName() { return name; } public Integer getVersion() { return version; }}
@Getter@RequiredArgsConstructorclass MyService { private final String name; private final Integer version;}
6
Getting rid from annoying code duplicationpublic String validate(Object input) { if (income instanceof String
&& !((String) income).isEmpty()) { return (String) income; } …}
public String validate(Object input) { if (income instanceof String && !income.isEmpty()) { return income; } …}
8
Two ways to generate code
Annotation Processing
▷Java 5+▷Takes java code and generates source files
▷You can not manipulate an existing java code
▷Use the model of processing rounds
Javac Plugin
▷Since Java 8▷Can give us access to AST trees parsed from source code
▷Can be used to add compile-time checks
▷Can run on different phases of compilation process
Annotation processor
1. Implement AbstractProcessor interface
import javax.annotation.processing.AbstractProcessor;
class MyProcessor implements AbstractProcessor {
@Override public boolean process(
Set<? Extends TypeElement> annotations, RoundEnvironment roundEnv) {
/*...*/ }
}
2. Create provider-configuration file
MyProcessor.jar- com/example
- MyProcessor.class- META-INF/services
- javax.annotation.processing.Processor
Provider-configuration file should declare all annotation processors you want to expose.
3. Compilation
$ javac –cp processor.jar \ *sources*.java
Javac plugin
1. Implement Plugin interfaceimport com.sun.source.util.Plugin;
class MyPlugin implements Plugin { @Override public String getName() { return “pluginName”; }
@Override public void init(JavacTask javacTask,
String… strings) { /*...*/ }}
2. Create provider-configuration file
MyPlugin.jar- com/example
- MyPlugin.class- META-INF/services
- com.sun.source.util.Plugin
Provider-configuration file should declare all plugins you want to expose.
3. Compilation
$ javac -Xplugin:PluginName \ –cp /path/to/plugin \
Source.java
Demo
Questions?