Open the file
${GLASSFISH_HOME}/glassfish/config/osgi.propertiesand add this line at the end:
jre-1.8=${jre-1.7}
Happy Coding!
${GLASSFISH_HOME}/glassfish/config/osgi.propertiesand add this line at the end:
jre-1.8=${jre-1.7}
Since Java EE 6 you can invoke Interceptors around method calls. With Interceptors you will add Aspect-oriented Programming (AoP) patterns to your Java EE project. Given you have a method bound to an Interceptor a method call will look like this:
To actually implement this behavior there are some simple steps to do. First implement an Interceptor:
@javax.interceptor.Interceptor public class OurInterceptor { @javax.interceptor.AroundInvoke public Object someMethodName(InvocationContext context) throws Exception { // do something before method System.out.println(">before"); //executing source method Object result = context.proceed(); // do something after method System.out.println("<after"); return result; } }
And register our Interceptor in the beans.xml
:
de.beanbelt.bbinterceptorsandreapeatableannotations.interceptors.OurInterceptor
Now you can simply invoke this Interceptor by annotating a class or method in e.g. an Stateless EJB.
@Stateless // interceptor will be invoked on every method in OurService @javax.interceptor.Interceptors(OurInterceptor.class) public class OurService { // You can invoke an Interceptor on one method only // Note: this will overwrite the class-level Interceptor //@Interceptors(OurInterceptor.class) public String getName(long id) { System.out.println("method"); return database.get(id).getName(); } }
If you execute the code the following will be printed to the console:
>before method <after
Now we extends the example by our own annotations which will invoke the interceptor. Create an annotation that looks like the following:
@Inherited @InterceptorBinding @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface OurAnnotation { @Nonbinding boolean someValue() default false; }
And change the Interceptor like this:
@OurAnnotation @javax.interceptor.Interceptor public class OurInterceptor{...}
Now we can use the interceptor on method-level in OurService like this:
@Stateless public class OurService { @OurAnnotation(someValue=true) public String getName(long id) { System.out.println("method"); return database.get(id).getName(); } }
As you can see, we can pass parameters to the Annotation which we can read in our interceptor like this:
@OurAnnotation @javax.interceptor.Interceptor public class OurInterceptor{ @javax.interceptor.AroundInvoke public Object someMethodName(InvocationContext context) throws Exception { Method method = context.getMethod(); if (method.isAnnotationPresent(OurAnnotation.class)) { boolean someValue = method.getAnnotation(OurAnnotation.class).someValue(); System.out.println("someValue is: "+someValue); } // do something before method System.out.println(">before"); //executing source method Object result = context.proceed(); // do something after method System.out.println("<after"); return result; }
Since we annotated our method with someValue=true the output on the console will look like this:
someValue is: true >before method <after
So far so good but what happens if we want to annotate our method multiple times like this?
@OurAnnotation(someValue=false) @OurAnnotation(someValue=true) public String getName(long id) {...}
We have to create a grouping Annotation (Note the S in OurAnnotationS).
@Inherited @InterceptorBinding @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface OurAnnotations { @Nonbinding OurAnnotation[] value(); }
Now we can annotate our method like this:
@OurAnnotations({ @OurAnnotation(someValue=false), @OurAnnotation(someValue=true) }) public String getName(long id) {...}
In Java 8 we can use the Repeatable Annotations feature. To do so we just need to add an Annotation to @OurAnnotation
@Inherited @Repeatable(OurAnnotations.class) @InterceptorBinding @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface OurAnnotation {...}
Now we can annotate our method as we stated before:
@OurAnnotation(someValue=false) @OurAnnotation(someValue=true) public String getName(long id) {...}
But what happened to the Interceptor, why is it not working anymore? Well, we have to implement a new interceptor for our grouping Annotation like this:
@OurAnnotations @javax.interceptor.Interceptor public class OurGroupingInterceptor{ @javax.interceptor.AroundInvoke public Object someMethodName(InvocationContext context) throws Exception { Method method = context.getMethod(); if (method.isAnnotationPresent(OurAnnotations.class)) { OurAnnotation[] ourAnnotations = method.getAnnotation(OurAnnotations.class).value(); for (OurAnnotation annotation : ourAnnotations) { System.out.println("someValue is: "+ annotation.someValue()); } } // do something before method System.out.println(">before"); //executing source method Object result = context.proceed(); // do something after method System.out.println("<after"); return result; } }
Now the output on the console will look like this:
someValue is: false someValue is: true >before method <after
Now we successfully implemented an Interceptor with our own Annotation which we can repeat like we want.