-
1. Re: Annotation processing in Seam
asookazian Jul 26, 2009 12:13 AM (in response to asookazian)Well, I found this in wikipedia:
Processing
When Java source code is compiled, annotations can be processed by compiler plug-ins called annotation processors. Processors can produce informational messages or create additional Java source files or resources, which in turn may be compiled and processed, but processors cannot modify the annotated code itself. The Java compiler conditionally stores annotation metadata in the class files if the annotation has a RetentionPolicy of CLASS or RUNTIME. Later, the JVM or other programs can look for the metadata to determine how to interact with the program elements or change their behavior.so how does this work in a Seam app runtime context?
-
2. Re: Annotation processing in Seam
joblini Jul 26, 2009 12:34 AM (in response to asookazian)Hi Arbi,
In a nutshell, Seam generates proxies for components (Java classes annotated with @Name). Calls to methods on the component are thus intercepted by the proxy, which can then examine the annotations and perform the appropriate processing.
Regards,
Ingo -
3. Re: Annotation processing in Seam
asookazian Jul 27, 2009 7:49 AM (in response to asookazian)What class(es) do the actuall annotation processing? I looked in the Seam core packages and there are some Java Reflection API usage.
I wrote the following class to simulate this:
@Name("testReflections") @Startup @Scope(ScopeType.APPLICATION) public class TestReflections { @Logger private Log log; @Create public void init(){ getAnnotations("org.jboss.seam.example.booking.BookingListAction"); } private void getAnnotations(String myClass) { try { Class clazz = Class.forName(myClass); Method[] methods = clazz.getMethods(); java.lang.annotation.Annotation[] annotations = null; for (int i = 0; i < methods.length; i++) { log.info("methods[i].toString(): "+methods[i].toString()); annotations = methods[i].getAnnotations(); for(int j = 0; j < annotations.length; j++){ java.lang.annotation.Annotation annotation = annotations[j]; log.info("annotation.toString() = "+annotation.toString()); } } log.info("***********************************************************************************"); } catch (ClassNotFoundException e) { log.error("error found: ", e); } } }
Output:
22:43:33,295 INFO [TestReflections] methods[i].toString(): public void org.jboss.seam.example.booking.BookingListAction.destroy() 22:43:33,298 INFO [TestReflections] annotation.toString() = @javax.ejb.Remove(retainIfException=false) 22:43:33,299 INFO [TestReflections] methods[i].toString(): public void org.jboss.seam.example.booking.BookingListAction.cancel() 22:43:33,299 INFO [TestReflections] methods[i].toString(): public void org.jboss.seam.example.booking.BookingListAction.getBookings() 22:43:33,301 INFO [TestReflections] annotation.toString() = @org.jboss.seam.annotations.Factory(value=, autoCreate=false, scope=UNSPECIFIED) 22:43:33,302 INFO [TestReflections] annotation.toString() = @org.jboss.seam.annotations.Observer(value=[bookingConfirmed], create=true) 22:43:33,302 INFO [TestReflections] methods[i].toString(): public org.jboss.seam.example.booking.Booking org.jboss.seam.example.booking.BookingListAction.getBooking() 22:43:33,302 INFO [TestReflections] methods[i].toString(): public native int java.lang.Object.hashCode() 22:43:33,302 INFO [TestReflections] methods[i].toString(): public final native java.lang.Class java.lang.Object.getClass() 22:43:33,302 INFO [TestReflections] methods[i].toString(): public final void java.lang.Object.wait() throws java.lang.InterruptedException 22:43:33,302 INFO [TestReflections] methods[i].toString(): public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException 22:43:33,302 INFO [TestReflections] methods[i].toString(): public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException 22:43:33,302 INFO [TestReflections] methods[i].toString(): public boolean java.lang.Object.equals(java.lang.Object) 22:43:33,302 INFO [TestReflections] methods[i].toString(): public final native void java.lang.Object.notify() 22:43:33,302 INFO [TestReflections] methods[i].toString(): public final native void java.lang.Object.notifyAll() 22:43:33,303 INFO [TestReflections] methods[i].toString(): public java.lang.String java.lang.Object.toString() 22:43:33,303 INFO [TestReflections] ***********************************************************************************
-
4. Re: Annotation processing in Seam
asookazian Nov 8, 2009 7:51 PM (in response to asookazian)
Ingo Jobling wrote on Jul 26, 2009 00:34:
Hi Arbi,
In a nutshell, Seam generates proxies for components (Java classes annotated with @Name). Calls to methods on the component are thus intercepted by the proxy, which can then examine the annotations and perform the appropriate processing.
Regards,
IngoThe keyword 'proxy' is not in the index for DAllen or Yuan books. In the Seam 2.1.2 ref doc the only reference to 'proxy' is in the context of remoting and Spring integration.
Someone plz shed add'l light on this...
-
5. Re: Annotation processing in Seam
cash1981 Nov 8, 2009 7:57 PM (in response to asookazian)Hi Arbi. I wondered the same thing, and I looked in the source code and figured it out. I was looking at the RequestParameter annotation.
Seam uses reflection to load all annotations, and if for instance the RequestParameter annotation is there, then it know what to perform, in this case using the name of the variable and getting the value from the request. I didn't dig further, but I am pretty sure thats how they intercept and use annotations with Seam.
-
6. Re: Annotation processing in Seam
kapitanpetko Nov 9, 2009 2:31 AM (in response to asookazian)
Arbi Sookazian wrote on Jul 27, 2009 07:49:
What class(es) do the actuall annotation processing? I looked in the Seam core packages and there are some Java Reflection API usage.As usual, Seam uses interceptors. Annotations are just metatdata for a method or a class, Seam inspects those (using reflection) and decides what to do. So for example, there is a ConverstationIntreceptor (as usual, there are lots of TODO's...):
else if ( method.isAnnotationPresent(Begin.class) ) { String[] outcomes = method.getAnnotation(Begin.class).ifOutcome(); if ( outcomes.length==0 || Arrays.asList(outcomes).contains(result) ) { beginConversation( method.getAnnotation(Begin.class).nested(), getProcessDefinitionName(method) ); setFlushMode(method); //TODO: what if conversation already exists? Or a nested conversation? } }
There is of course BijectionInterceptor, EventInterceptor, etc. Grep the source to find more.