More Related Content
Similar to JavaOne 2017 CON3282 - Code Generation with Annotation Processors: State of the Art in Java 9 (20)
More from Jorge Hidalgo (20)
JavaOne 2017 CON3282 - Code Generation with Annotation Processors: State of the Art in Java 9
- 2. ABOUT THE SPEAKERS
Copyright © 2017 Accenture. All rights reserved. 2
Welcome to our session!
Julio Palma Vázquez
Member – Málaga JUG
Technology Architect – Accenture Technology
Accenture Global Java Champion
Accenture Delivery Center in Spain
Mountain biker, AD&D player, Sid Meier’s Civilization gamer,
LotR fan, …
@restalion
https://github.com/restalion
Jorge Hidalgo
Coordinator – Málaga JUG
Global Java Lead – Accenture Technology
Java, Architecture & DevOps Lead
Accenture Delivery Center in Spain
Father of two children, husband, whistle player, video gamer, sci-
fi ‘junkie’, Star Wars ‘addict’, Lego brick ‘wielder’, Raspberry Pi
fan, … LLAP!
@_deors
https://github.com/deors
- 3. • Overview of Annotations and Annotation Processors in Java
• What’s new in Java 9 APT API
• Learn how to create Annotation Processors
• Learn how to use Annotation Processors to generate source code
• Annotation Processors and Modules in Java 9
• With lots of examples and source code
CODE GENERATION IN THE JAVA COMPILER
Copyright © 2017 Accenture. All rights reserved. 3
Objetives for the session
- 4. Please raise your hands if you are familiar with Annotations, know how to use them or are
even capable of writing Annotation Types
POLL #1
Copyright © 2017 Accenture. All rights reserved. 4
- 6. • Annotations were first introduced in Java 5
• Add metadata capabilities to the Java language:
• Build/deployment information
• Configuration properties
• Compiler behavior
• Quality checks
• Dependency injection
• Persistence mapping
• ...
ANNOTATIONS IN THE JAVA LANGUAGE
Copyright © 2017 Accenture. All rights reserved. 6
History
- 7. • Annotations always appear before the annotated piece of code
• Annotations can ‘decorate’...
• Packages
• Types (classes, interfaces, enums, annotation types)
• Variables (class, instance and local variables)
• Constructors, methods and their parameters
• Generic type parameter (since Java 8)
• Any type use (since Java 8)
ANNOTATIONS IN THE JAVA LANGUAGE
Copyright © 2017 Accenture. All rights reserved. 7
Overview
- 8. • Can be grouped, nested, repeated... very powerful!
Map<@NonNull String, @NonEmpty List<@Readonly Document>> docStore;
• Annotations may be used just as a ‘marker’
@NonNull String email;
• They may contain name-value pairs, and arrays
@Author(name = "Albert",
created = "17/09/2010",
revision = 3,
reviewers = {"George", "Fred"})
public class SomeClass {...}
• Can be defined with default values, and then omitted when used
• When it has only one attribute named value, it can be omitted, too
@DatabaseTable(“MY_TABLE”) public class MyTable {...}
ANNOTATIONS IN THE JAVA LANGUAGE
Copyright © 2017 Accenture. All rights reserved. 8
Overview
- 10. Please raise your hands if you are familiar with Annotation Processors, their capabilities or
know how to write new ones
POLL #2
Copyright © 2017 Accenture. All rights reserved. 10
- 11. • A special type of interface
public @interface Author {
String name();
String created();
int revision() default 1;
String[] reviewers() default {};
}
• Only primitives, enum types, annotation types, String, Class and arrays of them are
allowed as elements
• May be annotated itself, i.e. to define the retention policy or targets
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
public @interface Author {...}
Can trigger custom actions at compile time managed by
Annotation Processors!
ANNOTATIONS
Copyright © 2017 Accenture. All rights reserved. 11
Create an Annotation Type
- 12. • Annotation Processor:
– Implements javax.annotation.processing.Processor
– Or extends javax.annotation.processing.AbstractProcessor
• May use three annotations to configure itself:
– jx.a.p.SupportedAnnotationTypes – Used to flag which Annotation Types are managed by the
– jx.a.p.SupportedSourceVersion – Used to flag the latest Java source level supported by the processor
– jx.a.p.SupportedOptions – Used to register custom parameters that may be passed through the
• TL;DR – Implement the process() method
ANNOTATION PROCESSORS
Copyright © 2017 Accenture. All rights reserved. 12
Annotation Processing API
- 13. • Annotation processing happens in ‘rounds’
• In each round, a subset of sources are compiled, and then
processors matching the annotations found on those sources
are called
• Processing ends when no more sources/annotations are
pending
• Processors may claim all annotation types with a wildcard
• process() method has two parameters:
– Set<? extends jx.lang.model.element.TypeElement> – subset of annotations being processed
– jx.a.p.RoundEnvironment – access to information about the current and previous round
ANNOTATION PROCESSORS
Copyright © 2017 Accenture. All rights reserved. 13
Annotation Processing API
- 14. jx.a.p.ProcessingEnvironment also provides access to the Filer utility that allows for easy file creation
• Files are placed in the right folder as required by the compiler settings
• Folder hierarchy matching the package name
JavaFileObject jfo = processingEnv.getFiler()
.createSourceFile(newClassQualifiedName);
Writer writer = jfo.openWriter();
...or...
JavaFileObject jfo = processingEnv.getFiler()
.createClassFile(newClassQualifiedName);
OutputStream os = jfo.openOutputStream();
ANNOTATION PROCESSORS
Copyright © 2017 Accenture. All rights reserved. 14
Creating Files
- 15. Annotation Processors leverage the standard services mechanism
• Package the processors in a Jar file
• Include file META-INF/services/javax.annotation.processing.Processor
• Contents are the fully qualified names of the bundled processors, one per line
ANNOTATION PROCESSORS
Copyright © 2017 Accenture. All rights reserved. 15
How the compiler knows?
- 16. Find more information about APT in JavaOne 2014 session:
https://www.slideshare.net/deors/javaone-2014-con2013-code-generation-in-the-java-compiler-annotation-processors-do-the-hard-work
https://www.youtube.com/watch?v=xswPPwYPAFM
ANNOTATION PROCESSORS
Copyright © 2017 Accenture. All rights reserved. 16
Running Annotation Processors
- 17. Multiple ways:
• javac
• Apache Maven builds
• Continuous Integration builds
• IDE
ANNOTATION PROCESSORS
Copyright © 2017 Accenture. All rights reserved. 17
Running Annotation Processors
- 19. • Update <java.version> tag in pom.xml
<java.version>1.9</java.version>
• Update version of maven-compiler-plugin
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
• Upgrade the supported source version in Processor class
@SupportedAnnotationTypes(“com.foo.AnnotationSample")
@SupportedSourceVersion(SourceVersion.RELEASE_9)
public class AnnotationSampleProcessor
ADAPT LEGACY CODE
Copyright © 2017 Accenture. All rights reserved. 19
Upgrading your code to Java 9
- 20. • mvn clean install finish without errors:
ANNOTATIONS API IN JAVA 9
Copyright © 2017 Accenture. All rights reserved. 20
Upgrading your code to Java 9
- 22. Upgraded legacy code sample can be found in github:
https://github.com/deors/deors.demos.annotations
ADAPT LEGACY CODE
Copyright © 2017 Accenture. All rights reserved. 22
Upgrading your code to Java 9
- 24. ANNOTATIONS API IN JAVA 9
Copyright © 2017 Accenture. All rights reserved. 24
Overview
• New @Generated Annotation
• To add information about the annotation processor, date, and comments:
@Generated(value = "com.foo.processors.SampleProcessor",
date = "2017-09-28T09:43:28.170886",
comments = "Sample")
• Processed as a subsequent step by the annotation processor.
• Two new methods in RoundEnvironment interface
• Simplify processing of multiple annotations
default Set<? extends Element> getElementsAnnotatedWithAny(
Set<Class<? extends Annotation>> annotations);
default Set<? extends Element> getElementsAnnotatedWithAny(
TypeElement... annotations);
- 25. ANNOTATIONS API IN JAVA 9
Copyright © 2017 Accenture. All rights reserved. 25
Overview
• Changes in all methods of Filer interface.
To manage files in a module, module name is prefixed to the type name and separated using a
“/” character, i.e.:
JavaFileObject jfo = processingEnv.getFiler().createSourceFile(
"com.foo/com.foo.Bar");
JavaFileObject jfo = processingEnv.getFiler().getResource(location,
"com.foo/com.foo", "Bar");
- 26. NEW FEATURES IN JAVA 9
Copyright © 2017 Accenture. All rights reserved. 26
• It’s a best practice to include this annotation in the generated code:
bw.append("@Generated(value = "" + this.getClass().getName() +
"" , date = "" +
LocalDateTime.now() +
"", comments = "Test generator")");
Generated Annotation
Comments
MUST have the name of
the code generator
Date when the source was generated
- 27. • During annotation processing,the Generated annotation will be found but nothing is done,
it’s just informational.
• Generated code:
NEW FEATURES IN JAVA 9
Copyright © 2017 Accenture. All rights reserved. 27
Generated Annotation
Name of the code generator
Generation date Comments
- 30. ANNOTATION PROCESSORS AND MODULES
Copyright © 2017 Accenture. All rights reserved. 30
Creating classes in modules
• In previous examples we have three
different jar files:
• Annotation type
• Annotation processor
• classes that use annotations
• Dependencies are managed using the
regular classpath
30
annotation
annotation.processor
client
- 31. ANNOTATION PROCESSORS AND MODULES
Copyright © 2017 Accenture. All rights reserved. 31
Grouping classes in modules
• One module per jar file.
• Put a module-info.java file into each module.
• Each module-info file needs to define exported
packages and required modules.
annotation
annotation.processor
client
- 32. ANNOTATION PROCESSORS AND MODULES
Copyright © 2017 Accenture. All rights reserved. 32
Creating classes in modules
annotation module:
module com.foo.annotation {
exports com.foo.annotation;
}
annotation.processor module:
module com.foo.annotation.processors {
requires com.foo.annotation;
requires java.compiler;
}
client module:
module com.foo.client {
exports com.foo.client;
requires com.foo.annotation;
requires java.compiler;
}
Why? Because we add
@Generated annotation
annotation
annotation.processor
client
- 33. ANNOTATION PROCESSORS AND MODULES
Copyright © 2017 Accenture. All rights reserved. 33
Creating classes in modules
DEMO
https://github.com/restalion/deors.demos.annotations/tree/jdk9
- 34. Copyright © 2017 Accenture. All rights reserved. 34
• APT API is as powerful as in previous versions.
• All your legacy code still works as expected.
• You can add a couple a of new functionalities:
• @Generator annotation
• Simplified processing of multiple annotations
• You can also manage file generation in other modules
SUMMARY
- 35. Q & A
Copyright © 2017 Accenture. All rights reserved. 35
Many thanks for attending!
@_deors
https://github.com/deors
@restalion
https://github.com/restalion