fun with java annotations brian mcginnis. java annotations introduced in “tiger” release (java...

26
Fun with Java Fun with Java Annotations Annotations Brian McGinnis Brian McGinnis

Upload: moris-pope

Post on 31-Dec-2015

239 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Fun with Java Fun with Java AnnotationsAnnotations

Brian McGinnisBrian McGinnis

Page 2: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Java AnnotationsJava Annotations

Introduced in “Tiger” release (Java Introduced in “Tiger” release (Java 1.5)1.5)

One of most interesting Java One of most interesting Java extension in a long timeextension in a long time

Ability to declare metadata modifiers Ability to declare metadata modifiers for Java language upon:for Java language upon: Type declarations, Constructors, Type declarations, Constructors,

methods, Members, Parameters, methods, Members, Parameters, VariablesVariables

Page 3: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Standard Java 1.5 Standard Java 1.5 AnnotationsAnnotations

Tiger has some useful built-in annotationsTiger has some useful built-in annotations Java.lang.OverrideJava.lang.Override

Compiler enforces overriding superclass methodsCompiler enforces overriding superclass methods Java.lang.DeprecatedJava.lang.Deprecated

Warns when @deprecated method, class or member is Warns when @deprecated method, class or member is usedused

Must use javac “-deprecation” argument to javac or the Must use javac “-deprecation” argument to javac or the new -Xlint:deprecated flag to see compiler warningsnew -Xlint:deprecated flag to see compiler warnings

Java.lang.SupressWarningsJava.lang.SupressWarnings Useful for Tiger’s many compiler warnings (especially Useful for Tiger’s many compiler warnings (especially

with legacy collection code)with legacy collection code) KeyKey: Look for a string enclosed in “[ ]” in compiler : Look for a string enclosed in “[ ]” in compiler

warnings from javac (may need to use the command warnings from javac (may need to use the command line). Use this string to use for the @SuppressWarning line). Use this string to use for the @SuppressWarning argument.argument.

This may work on your compiler yet!This may work on your compiler yet!

Page 4: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

@Override Example@Override Example

@Override Example Code:@Override Example Code:

class Base {class Base { public void yes(int i) { }public void yes(int i) { }}}

class Subclass extends Base {class Subclass extends Base { @Override@Override public void yes(int i) { }public void yes(int i) { } @Override@Override public void no(float x) { } // Compiler error generated here!public void no(float x) { } // Compiler error generated here!}}

Page 5: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

@Deprecated Example@Deprecated ExampleExample usage:Example usage:

@Deprecated@Deprecatedpublic class DeprecatedExample {public class DeprecatedExample { private int x;private int x;

@Deprecated@Deprecated public int value;public int value;

@Deprecated@Deprecated public void setValue(int aValue) { value = aValue; }public void setValue(int aValue) { value = aValue; }}}

public class DeprecatedExampleUse { public class DeprecatedExampleUse { public static void main(String argv[])public static void main(String argv[]) {{ DeprecatedExample obj = new DeprecatedExample(); // Compiler WARNINGs DeprecatedExample obj = new DeprecatedExample(); // Compiler WARNINGs

generated heregenerated here obj.value = 10; // Compiler WARNING generated hereobj.value = 10; // Compiler WARNING generated here }}}}

Page 6: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

@SuppressWarning @SuppressWarning ExampleExample

public class SuppressExample {public class SuppressExample { List wordList = new ArrayList(); // no typing information on the ListList wordList = new ArrayList(); // no typing information on the List

private voidprivate void generateWarning()generateWarning() {{ wordList.add("foo"); // Warning generated here.wordList.add("foo"); // Warning generated here. }}}}javac -Xlint:unchecked SuppressExample.javajavac -Xlint:unchecked SuppressExample.javaSuppressExample.java:13: warning: [unchecked] unchecked call to add(E) as a member SuppressExample.java:13: warning: [unchecked] unchecked call to add(E) as a member

of the raw type java.util.Listof the raw type java.util.List wordList.add("foo"); // Warning generated here.wordList.add("foo"); // Warning generated here. ^̂1 warning1 warning

Get rid of warning by adding this line above the method Get rid of warning by adding this line above the method delcaration:delcaration:

@SuppressWarning(“unchecked”)@SuppressWarning(“unchecked”)

Page 7: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Setting Annotation Setting Annotation ValuesValues

Setting Annotation ValuesSetting Annotation Values Set arguments as key/value pairsSet arguments as key/value pairs Can optionally be an array of key value pairsCan optionally be an array of key value pairs

““Marker” annotationsMarker” annotations No argumentsNo arguments Example: @DeprecatedExample: @Deprecated

Single value annotationsSingle value annotations no key is required, just a valueno key is required, just a value Example: @SuppressExample(“unchecked”)Example: @SuppressExample(“unchecked”)

Multiple value annotationsMultiple value annotations separate key/value pairs with commasseparate key/value pairs with commas Example: @Review(student=“Jonny Law”, Example: @Review(student=“Jonny Law”,

grade=Grades.Pass)grade=Grades.Pass)

Page 8: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Java AnnotationsJava Annotations

Metadata from annotations is Metadata from annotations is available at compile-time and at available at compile-time and at runtimeruntime

What for?What for? compile-time uses: Tools like a code compile-time uses: Tools like a code

generator or code validator (e.g. generator or code validator (e.g. java.lang.Override)java.lang.Override)

runtime uses: Any framework or runtime uses: Any framework or application code that can make use of application code that can make use of metadata (e.g. J2EE)metadata (e.g. J2EE)

Page 9: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Implementing Implementing and using custom and using custom

annotationsannotations

Page 10: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

A Sample Annotation A Sample Annotation ApplicationApplication

A simple example to demo custom annotationsA simple example to demo custom annotations The demo application is: We want to readily The demo application is: We want to readily

identify design patterns used in our production identify design patterns used in our production codecode

Users put in annotation “@Pattern” to identify Users put in annotation “@Pattern” to identify design patterns in their codedesign patterns in their code

Our @Pattern annotation takes 3 arguments:Our @Pattern annotation takes 3 arguments: PatternTypePatternType = an enum for which design pattern (e.g. = an enum for which design pattern (e.g.

singleton, builder, etc.)singleton, builder, etc.) RoleRole = a string to denote the role played in more = a string to denote the role played in more

complex patterns (e.g. for an MVC pattern, complex patterns (e.g. for an MVC pattern, role=“controller”)role=“controller”)

MsgMsg = a string to further explain pattern usage = a string to further explain pattern usage

Page 11: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Sample usage #1Sample usage #1package samples.myapp;package samples.myapp;import custom.annotation.Pattern;import custom.annotation.Pattern;import custom.annotation.PatternType;import custom.annotation.PatternType;

/** An example singleton that uses our @Pattern annotation. *//** An example singleton that uses our @Pattern annotation. */@Pattern(type=PatternType.SINGLETON, msg=“Singleton wrapper @Pattern(type=PatternType.SINGLETON, msg=“Singleton wrapper

class”)class”)public class SampleOne {public class SampleOne { private static SampleOne instance = null;private static SampleOne instance = null; private SampleOne() { }private SampleOne() { } public static SampleOne public static SampleOne get() get() { { if (instance == null)if (instance == null) instance = new SampleOne();instance = new SampleOne(); return(instance); return(instance); }}}}

Page 12: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Sample Usage #2Sample Usage #2package samples.myapp;package samples.myapp;import custom.annotation.Pattern;import custom.annotation.Pattern;import custom.annotation.PatternType;import custom.annotation.PatternType;

/** An example class that uses our @Pattern annotation. *//** An example class that uses our @Pattern annotation. */public class SampleTwo {public class SampleTwo { @Pattern(type=PatternType.FACTORY , role="static factory @Pattern(type=PatternType.FACTORY , role="static factory

method")method") public static SampleTwopublic static SampleTwo create(int aValue)create(int aValue) {{ SampleTwo instance = new SampleTwo(aValue);SampleTwo instance = new SampleTwo(aValue); return(instance);return(instance); }} private int i; private int i; protected SampleTwo(int a) { i = a; }protected SampleTwo(int a) { i = a; } protected SampleTwo() { }protected SampleTwo() { }}}

Page 13: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Implementing Implementing AnnotationsAnnotations

4 standard 4 standard meta-annotationsmeta-annotations you need to you need to know about:know about: @Target – specifies which Java elements can use @Target – specifies which Java elements can use

the annotation (e.g. Type, method, constructor, the annotation (e.g. Type, method, constructor, etc.)etc.)

@Retention – specifies if annotation info is @Retention – specifies if annotation info is available at compile-time or at runtimeavailable at compile-time or at runtime

@Documented – Indicates if annotation should be @Documented – Indicates if annotation should be part of public api. Annotation use shows up in part of public api. Annotation use shows up in javadoc.javadoc.

@Inherited – Specify inheritance handling of the @Inherited – Specify inheritance handling of the annotationannotation

Page 14: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Implementing Implementing annotationsannotations

1.1. Declare meta-annotations for you Declare meta-annotations for you custom annotation in the java filecustom annotation in the java file

Example: @Target, @Documented, Example: @Target, @Documented, etc.etc.

2.2. Declare an @interface for your Declare an @interface for your custom annotation in the java filecustom annotation in the java file

Similar to a regular Java ‘interface’Similar to a regular Java ‘interface’ Define “properties” of the annotation Define “properties” of the annotation

as methodsas methods

Page 15: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Annotation Annotation ImplementationImplementation

package custom.annotation;package custom.annotation;Import ….Import ….

// Specify our meta-annoations here.// Specify our meta-annoations here.@Target({ElementType.TYPE, ElementType.METHOD, @Target({ElementType.TYPE, ElementType.METHOD,

ElementType.FIELD })ElementType.FIELD })@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME) @Documented // Tell javadoc to include usage of our custom annotations@Documented // Tell javadoc to include usage of our custom annotations

public @interface Pattern {public @interface Pattern { // The design pattern enum value for the annotation instance.// The design pattern enum value for the annotation instance. PatternType type(); PatternType type(); // The "role" played in the design pattern. (value is optional)// The "role" played in the design pattern. (value is optional) String role() default "“;String role() default "“;

// Some text to be displayed played in the design pattern. (optional)// Some text to be displayed played in the design pattern. (optional) String msg() default "";String msg() default "";}}

Page 16: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Annotation Annotation ImplementationImplementation

package custom.annotation;package custom.annotation;

/** Declare the design patterns known by our custom @Pattern /** Declare the design patterns known by our custom @Pattern annotation. */ annotation. */

public enum PatternType {public enum PatternType { /** A class which wraps a singleton object instance... blah. *//** A class which wraps a singleton object instance... blah. */ SINGLETON_CLASS,SINGLETON_CLASS,

/** A method used to constructs an object instance... blah. *//** A method used to constructs an object instance... blah. */ FACTORY_METHOD, FACTORY_METHOD,

/** A class which is used to ... blah. *//** A class which is used to ... blah. */ BUILDER;BUILDER; public static String public static String getHtmlLink(PatternType pattern, String basePath) { … }getHtmlLink(PatternType pattern, String basePath) { … }}}

Page 17: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Tools to use our custom Tools to use our custom typetype

At runtime, you can get annotation At runtime, you can get annotation values from java classesvalues from java classes If you defined the annotation using If you defined the annotation using

@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME) Use java reflection to pickup annotations Use java reflection to pickup annotations

from methods, members, etc.from methods, members, etc. Demo a sample app which prints out all Demo a sample app which prints out all

design @Pattern we used in our design @Pattern we used in our application codeapplication code

Page 18: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Pattern Tool Source Pattern Tool Source CodeCodepublic class PatternTool { public class PatternTool {

/** Processes the @Pattern annotations for a java class. The meat of our tool. *//** Processes the @Pattern annotations for a java class. The meat of our tool. */ private void processPatternAnnotations(Class javaClass) throws private void processPatternAnnotations(Class javaClass) throws

IOExceptionIOException { { // Get the design @Pattern declared upon class declaration// Get the design @Pattern declared upon class declaration if (javaClass.if (javaClass.isAnnotationPresentisAnnotationPresent(Pattern.class)) {(Pattern.class)) { Pattern classLevelPattern = Pattern classLevelPattern =

(Pattern)(Pattern)javaClass.getAnnotationjavaClass.getAnnotation((Pattern.classPattern.class);); printClassPattern(classLevelPattern, javaClass.getName());printClassPattern(classLevelPattern, javaClass.getName()); }} // Get all design @Pattern declared upon methods via reflection// Get all design @Pattern declared upon methods via reflection Method[] methods = javaClass.getDeclaredMethods();Method[] methods = javaClass.getDeclaredMethods(); for (Method method : methods) {for (Method method : methods) {

method.setAccessible(true); // make private methods accessiblemethod.setAccessible(true); // make private methods accessible Pattern methodPattern = Pattern methodPattern = method.getAnnotationmethod.getAnnotation((Pattern.classPattern.class);); if (methodPattern != null) { if (methodPattern != null) { printMethodPattern(methodPattern, javaClass.getName(), printMethodPattern(methodPattern, javaClass.getName(),

method.getName());method.getName()); }} }} ……code removed for clarity…code removed for clarity…}}

Page 19: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Sample HTML OutputSample HTML Output

Design Pattern Usage Design Pattern Usage

Java Class: Java Class: samples.myapp.SampleOnesamples.myapp.SampleOne

Class level design pattern implemented: Class level design pattern implemented: Singleton Class Design PatternSingleton Class Design Pattern , Msg: , Msg: ‘Singleton Wrapper Class’‘Singleton Wrapper Class’

Java Class: Java Class: samples.myapp.SampleTwosamples.myapp.SampleTwo

Method Method create()create() implements design pattern: implements design pattern: Factory Method PatternFactory Method Pattern, Role: 'static , Role: 'static factory method' factory method'

Page 20: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Some Ideas on Some Ideas on how to apply how to apply annotationsannotationsThings to make you think Things to make you think

about how annotations can be about how annotations can be usedused

Page 21: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Replace older technologyReplace older technology Replace javadoc-oriented precompilersReplace javadoc-oriented precompilers

Provide runtime access to metadata - not just compile-Provide runtime access to metadata - not just compile-time.time.

Metadata syntax checked by java compilerMetadata syntax checked by java compiler Replace XML-oriented java toolsReplace XML-oriented java tools

Put metadata in your java files were it is easy to Put metadata in your java files were it is easy to maintain - not in separate XML filesmaintain - not in separate XML files

Do away with verbose, error-prone XML typingDo away with verbose, error-prone XML typing Typically easier to find and fix errors than fiddling with Typically easier to find and fix errors than fiddling with

the XML parsing + Java errorsthe XML parsing + Java errors Provide built-in type checking for metadata via java Provide built-in type checking for metadata via java

compilercompiler Rapidly replacing XML usage in J2EE in many Rapidly replacing XML usage in J2EE in many

areasareas

Page 22: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Application Idea: Binding a Application Idea: Binding a pojo to user interface formspojo to user interface forms@HtmlForm(posturl=“/congo/servlet/saveperson”, @HtmlForm(posturl=“/congo/servlet/saveperson”,

resetbutton=false)resetbutton=false)Public class PersonInfo {Public class PersonInfo {

@field(name=“pname”, type=FormField.TEXT, size=25, @field(name=“pname”, type=FormField.TEXT, size=25, isReqd=true)isReqd=true)@format(alignment=Align.LEFT, printf=“%s”)@format(alignment=Align.LEFT, printf=“%s”)public Sting name;public Sting name;

@field(name=“pstate”, type=FormField.RADIO, isReqd=true)@field(name=“pstate”, type=FormField.RADIO, isReqd=true)public State state;public State state;

@field(name=“page”, type=FormField.TEXT, isReq=false)@field(name=“page”, type=FormField.TEXT, isReq=false)@format(alignment=Align.RIGHT, printf=“%d”)@format(alignment=Align.RIGHT, printf=“%d”)public Integer age;public Integer age;……

}}

Page 23: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Application ideas: User Application ideas: User Input validationInput validation

@Validator(class=com.fubar.PersValid)@Validator(class=com.fubar.PersValid)public class PersonPojo {public class PersonPojo {

@range(min=1, max=115)@range(min=1, max=115)public int age;public int age;

@range(min=0, max=20)@range(min=0, max=20)@default(value=new Integer(0))@default(value=new Integer(0))@notnull(true)@notnull(true)public Integer numberOfDependents;public Integer numberOfDependents;

……}}

Page 24: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Application: EJB Application: EJB InterceptorsInterceptors

@Stateless@Stateless@Interceptors({com.acme.AccountAudit.class, com.acme.Metrics.class, com.acme.CustomSecurity.class})@Interceptors({com.acme.AccountAudit.class, com.acme.Metrics.class, com.acme.CustomSecurity.class})public class AccountManagementBean implements AccountManagement {public class AccountManagementBean implements AccountManagement {

public void createAccount(int accountNumber, AccountDetails details) { ... }public void createAccount(int accountNumber, AccountDetails details) { ... }......}}

public class Metrics {public class Metrics {@AroundInvoke@AroundInvoke public Object profile(InvocationContext inv) throws Exception { public Object profile(InvocationContext inv) throws Exception {

long time = System.currentTimeMillis();long time = System.currentTimeMillis();try { return inv.proceed(); } finally {try { return inv.proceed(); } finally {

long endTime = time - System.currentTimeMillis();long endTime = time - System.currentTimeMillis();System.out.println(inv.getMethod() + " took " + endTime + “ milliseconds.");System.out.println(inv.getMethod() + " took " + endTime + “ milliseconds.");

}}}}

}}

public class AccountAudit {public class AccountAudit {@AroundInvoke@AroundInvoke public Object auditAccountOperation(InvocationContext inv) throws Exception { public Object auditAccountOperation(InvocationContext inv) throws Exception {

try { try { Object result = inv.proceed();Object result = inv.proceed();Auditor.audit(inv.getMethod().getName(), inv.getParameters[0]);Auditor.audit(inv.getMethod().getName(), inv.getParameters[0]);return result;return result;

} catch (Exception ex) { Auditor.auditFailure(ex); } catch (Exception ex) { Auditor.auditFailure(ex); throw ex; }throw ex; }}}

}}public class CustomSecurity {public class CustomSecurity {

@AroundInvoke@AroundInvoke public Object customSecurity(InvocationContext inv) throws Exception…. public Object customSecurity(InvocationContext inv) throws Exception….

Page 25: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Application: EJB SecurityApplication: EJB Security@RolesAllowed(“sysadmin”)@RolesAllowed(“sysadmin”)public class Maintainence {public class Maintainence {

public void importCompanyData () {...}public void importCompanyData () {...}public void restart () {...}public void restart () {...}......

}}

@Stateless @Stateless public class HRActivity {public class HRActivity {

@RolesAllowed(“HR”)@RolesAllowed(“HR”)public void addToPayroll () {...}public void addToPayroll () {...}

@RolesAllowed({“HR”, “Manager”})@RolesAllowed({“HR”, “Manager”})public void postJobOpening() {...}public void postJobOpening() {...}......

}}

Page 26: Fun with Java Annotations Brian McGinnis. Java Annotations Introduced in “Tiger” release (Java 1.5) Introduced in “Tiger” release (Java 1.5) One of most

Application Idea: Code Application Idea: Code Maintentance AnnotationsMaintentance Annotations

Public class MyAppClass {Public class MyAppClass {

// Tags to generate documentation of SQL used in your application so it’s easier to// Tags to generate documentation of SQL used in your application so it’s easier to

// figure out implications of dbms schema changes and dbms tuning.// figure out implications of dbms schema changes and dbms tuning.

@SqlTracker(preparedQuery=sql)@SqlTracker(preparedQuery=sql)

protected static final String sql = “select id, version from astro_entity where type protected static final String sql = “select id, version from astro_entity where type = ?”;= ?”;

public ArrayList<SuperNova> getSuperNova(String snType) { ….}public ArrayList<SuperNova> getSuperNova(String snType) { ….}

// Tags to generate documentation on hacks and things todo for future releases.// Tags to generate documentation on hacks and things todo for future releases.

@Hack(problem=“Uses linear sort algorithm”, fix=“Use tree sort”)@Hack(problem=“Uses linear sort algorithm”, fix=“Use tree sort”)

@Refactor(idea=“move sorting to separate class”)@Refactor(idea=“move sorting to separate class”)

public voidpublic void

sortSuperNova(ArrayList<SuperNova> sn) sortSuperNova(ArrayList<SuperNova> sn)

{{

……

}}