SlideShare una empresa de Scribd logo
1 de 24
Descargar para leer sin conexión
On Processors,
Compilers and
@Configurations

Michael Pellaton
Netcetera
189
AGENDA

> Spring @Configuration classes
> An Annotation Processor for Validation
> Unit Testing the Annotation Processor




                                           2
Code Examples


The code in this presentation is simplified and doesn’t compile.


Full length, compiling version of the code:
http://github.com/pellaton/jazoon2012-talk




                                                              3
Spring @Configuration Classes


> Java-based Spring application context configuration
> An alternative to XML or annotation based configurations
> Example:

  @Configuration
  public class ExampleConfiguration {


      @Bean
      public Example exampleBean() {
          return new ExampleImpl();
      }
  }
                                                             4
Let’s Read the Javadoc…


          Must not            Must have a visible
           be final           no-arg constructor

                   @Configuration
  Must not
                   public class ExampleConfiguration {
  be Private
                                                                  ...
                       @Bean
                       public Example exampleBean() {
                         return new ExampleImpl();
    Must not           }
     be final      }                                              ...

                 Must not         should be static if returning
                return void      a BeanFactoryPostProcessor
                                                                        5
What If There’s Something Wrong?


Exception in thread "main"
 org...BeanDefinitionParsingException:
 Configuration problem: @Configuration class
 'ExampleConfiguration' may not be final.
 Remove the final modifier to continue.




                                               6
Your Developers




                  7
Annotation Processors


> Annotations can be processed at
  – Runtime  reflection (methods on Class, Method & Co)
  – Compile time  annotation processor

> JSR-269 “Pluggable Annotation Processing API”
  – Introduced with Java 6
  – Replaces “Annotation Processing Tool APT” of Java 5




                                                           8
JSR-269 Annotation Processors

> A Java compiler plugin
> An implementation of Processor
> Interacts through ProcessingEnvironment injected in init()
  – Messenger to emit compiler messages
  – Filer to create classes and resources
> Works with the Mirror (Model) API
  – Element represents a static Java language-level construct
     (class, package, method, …)
  – TypeMirror represents a Java type
> process() is called in rounds to process an annotation on a type
  – Access to current compilation/processing state through
    RoundEnvironment
  – May claim an annotation: subsequent processors are not called
                                                                     9
The Validating Annotation Processor


@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes(value = "org...Configuration")
public class JazoonProcessor extends AbstractProcessor {

 private Elements elementUtils;
 private Messager messager;
 private TypeElement configurationTypeElement;

 public synchronized void init(ProcessingEnvironment env) {
   elementUtils = env.getElementUtils();
   messager = env.getMessager();

     configurationTypeElement = elementUtils.getTypeElement(
         "org.springframework...Configuration");
 }

                                                               10
The Validating Annotation Processor


public boolean process(Set<? extends TypeElement> annotations,
     RoundEnvironment roundEnv) {
    if (!roundEnv.errorRaised() && !roundEnv.processingOver()) {
      for (TypeElement ann : annotations) {
        for (Element element : roundEnv.getElementsAnnotatedWith(ann)) {
          if (element instanceof TypeElement) {
                 processElement((TypeElement) element);
             }
         }
     }
    }
    // don’t consume the annotation type
    return false;
}                                                                    11
The Validating Annotation Processor


private void processElement(TypeElement typeElement) {

    for (AnnotationMirror ann : typeElement.getAnnotationMirrors()) {
      Element annTypeElement = ann.getAnnotationType().asElement();
      if (annTypeElement.equals(configurationTypeElement)) {

            if (typeElement.getModifiers().contains(Modifier.FINAL)) {
              messager.printMessage(Kind.ERROR,
                  "@Configuration classes must not be final.",
                  typeElement);
            }

        }
    }
}

                                                                         12
The Result




             13
The Result


$ mvn clean compile
...
[ERROR] Failed to execute goal ...: compile
Compilation failure:
[ERROR] /.../ExampleConfiguration.java:[7,13]
  error: @Configuration classes must not be final.
[ERROR] /.../ExampleConfiguration.java:[10,16]
  error: @Bean methods must not be private.



                                                 14
Your Developer

                 How about
                 unit testing
                 your code?




                                15
The Java Programming Language Compiler API


> Idea: A unit test that compiles (faulty) classes and checks
  the compiler output produced by the annotation processor

> JSR-199 The Java Programming Language Compiler API
  (Java 6)
> Programmatic interface to the Java compiler
> Requires a JDK




                                                                16
The Java Compiler API : Main Components


> The JavaCompiler is the
  – interface to the Java compiler
  – Factory for CompilationTasks
  – Instance is obtained through ToolProvider
> The CompilationTask is a future of a compilation task
> Source and class files are read and written using the
  JavaFileManager
> A message emitted during compilation is called a
  Diagnostic
> Diagnostics are stored by the DiagnosticCollector
                                                          17
The Java Compiler API : Main Components


                         ToolProvider

                                creates

                         JavaCompiler

                                creates

                        CompilationTask
         reads/writes
                                emits        listens
    java/class files
                                          holds
JavaFileManager           Diagnostic              DiagnosticCollector



                                                                    18
Compiling Classes in Unit Tests for Processors


/** Tests the detection of final @Configuration classes. */
@Test
public void finalConfigurationClass() throws IOException {


    List<Diagnostic> diagnostics =
      AnnotationProcessorTestCompiler.compileClass(
       "/com/github/pellaton/jazoon2012/FinalTestConfiguration.java",
       new JazoonProcessor());


    DiagnosticsAssert.assertContainsSingleMessage(Kind.ERROR, 16,
       diagnostics);
}

                                                                    19
Compiling Classes in Unit Tests for Processors

public static List<Diagnostic> compileClass(String clazzName,
    Processor processor) {


 DiagnosticCollector<> collector = new DiagnosticCollector<>();
 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
 Locale locale = Locale.getDefault();


 StandardJavaFileManager fileManager =
     compiler.getStandardFileManager(collector, locale, null);

 Iterable<? extends JavaFileObject> compilationUnits =
     fileManager.getJavaFileObjectsFromFiles(classToCompile);


 // the infrastructure is now ready                               20
Compiling Classes in Unit Tests for Processors


    // compile the class and return the result


    CompilationTask task = compiler.getTask(null, fileManager,
        collector, "-proc:only", null, compilationUnits);


    task.setProcessors(processor);
    task.call();


    return collector.getDiagnostics();
}




                                                                 21
The Result




             22
Conclusion


> Annotation processors can be used to extend the tooling and build beyond the
  traditional purposes like code generation
> To unit test an annotation processor, employ the Java compiler API
> @Configuration and other annotation-based frameworks:
  try hard to find problems as early as possible




                                                                                 23
Michael Pellaton    www.netcetera.com
Netcetera           michael.pellaton@netcetera.ch



Examples & Links:   github.com/pellaton/jazoon2012-talk

Más contenido relacionado

La actualidad más candente

Creating A Language Editor Using Dltk
Creating A Language Editor Using DltkCreating A Language Editor Using Dltk
Creating A Language Editor Using Dltk
Kaniska Mandal
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
Ray Ploski
 

La actualidad más candente (20)

Android Unit Test
Android Unit TestAndroid Unit Test
Android Unit Test
 
02 basic java programming and operators
02 basic java programming and operators02 basic java programming and operators
02 basic java programming and operators
 
Lecture 5 JSTL, custom tags, maven
Lecture 5   JSTL, custom tags, mavenLecture 5   JSTL, custom tags, maven
Lecture 5 JSTL, custom tags, maven
 
Spring 3 to 4
Spring 3 to 4Spring 3 to 4
Spring 3 to 4
 
J2ee standards > CDI
J2ee standards > CDIJ2ee standards > CDI
J2ee standards > CDI
 
Creating A Language Editor Using Dltk
Creating A Language Editor Using DltkCreating A Language Editor Using Dltk
Creating A Language Editor Using Dltk
 
Developing Agile Java Applications using Spring tools
Developing Agile Java Applications using Spring toolsDeveloping Agile Java Applications using Spring tools
Developing Agile Java Applications using Spring tools
 
JSUG - Tech Tips1 by Christoph Pickl
JSUG - Tech Tips1 by Christoph PicklJSUG - Tech Tips1 by Christoph Pickl
JSUG - Tech Tips1 by Christoph Pickl
 
Complete Java Course
Complete Java CourseComplete Java Course
Complete Java Course
 
[스프링/Spring교육학원,자바교육,근로자교육,실업자교육추천학원_탑크리에듀]#6.스프링프레임워크 & 마이바티스 (Spring Framew...
[스프링/Spring교육학원,자바교육,근로자교육,실업자교육추천학원_탑크리에듀]#6.스프링프레임워크 & 마이바티스 (Spring Framew...[스프링/Spring교육학원,자바교육,근로자교육,실업자교육추천학원_탑크리에듀]#6.스프링프레임워크 & 마이바티스 (Spring Framew...
[스프링/Spring교육학원,자바교육,근로자교육,실업자교육추천학원_탑크리에듀]#6.스프링프레임워크 & 마이바티스 (Spring Framew...
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
 
Spring
SpringSpring
Spring
 
Whats New in Java 5, 6, & 7 (Webinar Presentation - June 2013)
Whats New in Java 5, 6, & 7 (Webinar Presentation - June 2013)Whats New in Java 5, 6, & 7 (Webinar Presentation - June 2013)
Whats New in Java 5, 6, & 7 (Webinar Presentation - June 2013)
 
Advance Java
Advance JavaAdvance Java
Advance Java
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Java 9
Java 9Java 9
Java 9
 
PHP 7 Crash Course
PHP 7 Crash CoursePHP 7 Crash Course
PHP 7 Crash Course
 
Packages and inbuilt classes of java
Packages and inbuilt classes of javaPackages and inbuilt classes of java
Packages and inbuilt classes of java
 
Identifing Listeners and Filters
Identifing Listeners and FiltersIdentifing Listeners and Filters
Identifing Listeners and Filters
 
Using Contexts & Dependency Injection in the Java EE 6 Platform
Using Contexts & Dependency Injection in the Java EE 6 PlatformUsing Contexts & Dependency Injection in the Java EE 6 Platform
Using Contexts & Dependency Injection in the Java EE 6 Platform
 

Similar a On Processors, Compilers and @Configurations

Chapter 2.1
Chapter 2.1Chapter 2.1
Chapter 2.1
sotlsoc
 
imperative programming language, java, android
imperative programming language, java, androidimperative programming language, java, android
imperative programming language, java, android
i i
 
Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)
Gunith Devasurendra
 

Similar a On Processors, Compilers and @Configurations (20)

Annotation Processing
Annotation ProcessingAnnotation Processing
Annotation Processing
 
How to run java program without IDE
How to run java program without IDEHow to run java program without IDE
How to run java program without IDE
 
Annotation processing
Annotation processingAnnotation processing
Annotation processing
 
Annotation Processing in Android
Annotation Processing in AndroidAnnotation Processing in Android
Annotation Processing in Android
 
Chapter 2.1
Chapter 2.1Chapter 2.1
Chapter 2.1
 
Lecture - 2 Environment setup & JDK, JRE, JVM
Lecture - 2 Environment setup & JDK, JRE, JVMLecture - 2 Environment setup & JDK, JRE, JVM
Lecture - 2 Environment setup & JDK, JRE, JVM
 
Con-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistCon-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With Javassist
 
JAVA Program Examples
JAVA Program ExamplesJAVA Program Examples
JAVA Program Examples
 
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek PiotrowskiJDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
 
imperative programming language, java, android
imperative programming language, java, androidimperative programming language, java, android
imperative programming language, java, android
 
Basic java part_ii
Basic java part_iiBasic java part_ii
Basic java part_ii
 
Spring talk111204
Spring talk111204Spring talk111204
Spring talk111204
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Junit_.pptx
Junit_.pptxJunit_.pptx
Junit_.pptx
 
Java
JavaJava
Java
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
Java Basic PART I
Java Basic PART IJava Basic PART I
Java Basic PART I
 
Owner - Java properties reinvented.
Owner - Java properties reinvented.Owner - Java properties reinvented.
Owner - Java properties reinvented.
 
Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)
 
Java 8 Overview
Java 8 OverviewJava 8 Overview
Java 8 Overview
 

Más de Netcetera

Más de Netcetera (20)

Payment trend scouting - Kurt Schmid, Netcetera
Payment trend scouting - Kurt Schmid, NetceteraPayment trend scouting - Kurt Schmid, Netcetera
Payment trend scouting - Kurt Schmid, Netcetera
 
Boost your approved transaction volume - Ana Vuksanovikj Vaneska, Netcetera
Boost your approved transaction volume - Ana Vuksanovikj Vaneska, NetceteraBoost your approved transaction volume - Ana Vuksanovikj Vaneska, Netcetera
Boost your approved transaction volume - Ana Vuksanovikj Vaneska, Netcetera
 
Increase conversion, convenience and security in e-commerce checkouts - Silke...
Increase conversion, convenience and security in e-commerce checkouts - Silke...Increase conversion, convenience and security in e-commerce checkouts - Silke...
Increase conversion, convenience and security in e-commerce checkouts - Silke...
 
3-D Secure 2.0 - Stephan Rüdisüli, Netcetera & Patrick Juffern, INFORM
3-D Secure 2.0 - Stephan Rüdisüli, Netcetera & Patrick Juffern, INFORM3-D Secure 2.0 - Stephan Rüdisüli, Netcetera & Patrick Juffern, INFORM
3-D Secure 2.0 - Stephan Rüdisüli, Netcetera & Patrick Juffern, INFORM
 
Digital Payment in 2020 - Kurt Schmid, Netcetera
Digital Payment in 2020 - Kurt Schmid, NetceteraDigital Payment in 2020 - Kurt Schmid, Netcetera
Digital Payment in 2020 - Kurt Schmid, Netcetera
 
AI First. Erfolgsfaktoren für künstliche Intelligenz im Unternehmen
AI First. Erfolgsfaktoren für künstliche Intelligenz im UnternehmenAI First. Erfolgsfaktoren für künstliche Intelligenz im Unternehmen
AI First. Erfolgsfaktoren für künstliche Intelligenz im Unternehmen
 
Augmenting Maintenance
Augmenting MaintenanceAugmenting Maintenance
Augmenting Maintenance
 
Front-end up front
Front-end up frontFront-end up front
Front-end up front
 
The future of Prototpying
The future of PrototpyingThe future of Prototpying
The future of Prototpying
 
EMV Secure Remote Commerce (SRC)
EMV Secure Remote Commerce (SRC)EMV Secure Remote Commerce (SRC)
EMV Secure Remote Commerce (SRC)
 
Online shopping technology in the fast lane?
Online shopping technology in the fast lane?Online shopping technology in the fast lane?
Online shopping technology in the fast lane?
 
Merchant tokenization and EMV® Secure Remote Commerce
Merchant tokenization and EMV® Secure Remote CommerceMerchant tokenization and EMV® Secure Remote Commerce
Merchant tokenization and EMV® Secure Remote Commerce
 
Seamless 3-D Secure e-commerce experience
Seamless 3-D Secure e-commerce experienceSeamless 3-D Secure e-commerce experience
Seamless 3-D Secure e-commerce experience
 
Augmenting Health Care
Augmenting Health CareAugmenting Health Care
Augmenting Health Care
 
Driving transactional growth with 3-D Secure
Driving transactional growth with 3-D SecureDriving transactional growth with 3-D Secure
Driving transactional growth with 3-D Secure
 
Digital Payment Quo Vadis
Digital Payment Quo VadisDigital Payment Quo Vadis
Digital Payment Quo Vadis
 
EMV® Secure Remote Commerce
EMV® Secure Remote CommerceEMV® Secure Remote Commerce
EMV® Secure Remote Commerce
 
Context: The missing ingredient in multilingual software translation
Context: The missing ingredient in multilingual software translationContext: The missing ingredient in multilingual software translation
Context: The missing ingredient in multilingual software translation
 
Digital Payments - Netcetera Innovation Summit 2018
Digital Payments - Netcetera Innovation Summit 2018Digital Payments - Netcetera Innovation Summit 2018
Digital Payments - Netcetera Innovation Summit 2018
 
"Whats up and new at Netcetera?" - Netcetera Innovation Summit 2018
"Whats up and new at Netcetera?" - Netcetera Innovation Summit 2018"Whats up and new at Netcetera?" - Netcetera Innovation Summit 2018
"Whats up and new at Netcetera?" - Netcetera Innovation Summit 2018
 

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Último (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

On Processors, Compilers and @Configurations

  • 2. AGENDA > Spring @Configuration classes > An Annotation Processor for Validation > Unit Testing the Annotation Processor 2
  • 3. Code Examples The code in this presentation is simplified and doesn’t compile. Full length, compiling version of the code: http://github.com/pellaton/jazoon2012-talk 3
  • 4. Spring @Configuration Classes > Java-based Spring application context configuration > An alternative to XML or annotation based configurations > Example: @Configuration public class ExampleConfiguration { @Bean public Example exampleBean() { return new ExampleImpl(); } } 4
  • 5. Let’s Read the Javadoc… Must not Must have a visible be final no-arg constructor @Configuration Must not public class ExampleConfiguration { be Private ... @Bean public Example exampleBean() { return new ExampleImpl(); Must not } be final } ... Must not should be static if returning return void a BeanFactoryPostProcessor 5
  • 6. What If There’s Something Wrong? Exception in thread "main" org...BeanDefinitionParsingException: Configuration problem: @Configuration class 'ExampleConfiguration' may not be final. Remove the final modifier to continue. 6
  • 8. Annotation Processors > Annotations can be processed at – Runtime  reflection (methods on Class, Method & Co) – Compile time  annotation processor > JSR-269 “Pluggable Annotation Processing API” – Introduced with Java 6 – Replaces “Annotation Processing Tool APT” of Java 5 8
  • 9. JSR-269 Annotation Processors > A Java compiler plugin > An implementation of Processor > Interacts through ProcessingEnvironment injected in init() – Messenger to emit compiler messages – Filer to create classes and resources > Works with the Mirror (Model) API – Element represents a static Java language-level construct (class, package, method, …) – TypeMirror represents a Java type > process() is called in rounds to process an annotation on a type – Access to current compilation/processing state through RoundEnvironment – May claim an annotation: subsequent processors are not called 9
  • 10. The Validating Annotation Processor @SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes(value = "org...Configuration") public class JazoonProcessor extends AbstractProcessor { private Elements elementUtils; private Messager messager; private TypeElement configurationTypeElement; public synchronized void init(ProcessingEnvironment env) { elementUtils = env.getElementUtils(); messager = env.getMessager(); configurationTypeElement = elementUtils.getTypeElement( "org.springframework...Configuration"); } 10
  • 11. The Validating Annotation Processor public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (!roundEnv.errorRaised() && !roundEnv.processingOver()) { for (TypeElement ann : annotations) { for (Element element : roundEnv.getElementsAnnotatedWith(ann)) { if (element instanceof TypeElement) { processElement((TypeElement) element); } } } } // don’t consume the annotation type return false; } 11
  • 12. The Validating Annotation Processor private void processElement(TypeElement typeElement) { for (AnnotationMirror ann : typeElement.getAnnotationMirrors()) { Element annTypeElement = ann.getAnnotationType().asElement(); if (annTypeElement.equals(configurationTypeElement)) { if (typeElement.getModifiers().contains(Modifier.FINAL)) { messager.printMessage(Kind.ERROR, "@Configuration classes must not be final.", typeElement); } } } } 12
  • 14. The Result $ mvn clean compile ... [ERROR] Failed to execute goal ...: compile Compilation failure: [ERROR] /.../ExampleConfiguration.java:[7,13] error: @Configuration classes must not be final. [ERROR] /.../ExampleConfiguration.java:[10,16] error: @Bean methods must not be private. 14
  • 15. Your Developer How about unit testing your code? 15
  • 16. The Java Programming Language Compiler API > Idea: A unit test that compiles (faulty) classes and checks the compiler output produced by the annotation processor > JSR-199 The Java Programming Language Compiler API (Java 6) > Programmatic interface to the Java compiler > Requires a JDK 16
  • 17. The Java Compiler API : Main Components > The JavaCompiler is the – interface to the Java compiler – Factory for CompilationTasks – Instance is obtained through ToolProvider > The CompilationTask is a future of a compilation task > Source and class files are read and written using the JavaFileManager > A message emitted during compilation is called a Diagnostic > Diagnostics are stored by the DiagnosticCollector 17
  • 18. The Java Compiler API : Main Components ToolProvider creates JavaCompiler creates CompilationTask reads/writes emits listens java/class files holds JavaFileManager Diagnostic DiagnosticCollector 18
  • 19. Compiling Classes in Unit Tests for Processors /** Tests the detection of final @Configuration classes. */ @Test public void finalConfigurationClass() throws IOException { List<Diagnostic> diagnostics = AnnotationProcessorTestCompiler.compileClass( "/com/github/pellaton/jazoon2012/FinalTestConfiguration.java", new JazoonProcessor()); DiagnosticsAssert.assertContainsSingleMessage(Kind.ERROR, 16, diagnostics); } 19
  • 20. Compiling Classes in Unit Tests for Processors public static List<Diagnostic> compileClass(String clazzName, Processor processor) { DiagnosticCollector<> collector = new DiagnosticCollector<>(); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); Locale locale = Locale.getDefault(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(collector, locale, null); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(classToCompile); // the infrastructure is now ready 20
  • 21. Compiling Classes in Unit Tests for Processors // compile the class and return the result CompilationTask task = compiler.getTask(null, fileManager, collector, "-proc:only", null, compilationUnits); task.setProcessors(processor); task.call(); return collector.getDiagnostics(); } 21
  • 23. Conclusion > Annotation processors can be used to extend the tooling and build beyond the traditional purposes like code generation > To unit test an annotation processor, employ the Java compiler API > @Configuration and other annotation-based frameworks: try hard to find problems as early as possible 23
  • 24. Michael Pellaton www.netcetera.com Netcetera michael.pellaton@netcetera.ch Examples & Links: github.com/pellaton/jazoon2012-talk