Type: New Feature
Affects Version/s: 6.0.0, 8.6.3
Fix Version/s: 9.6.0
Component/s: Databind 2
Security Level: Jimmy
Spring 3.1, Hibernate 3.6, Apache Tomcat 7.0
When proxying a ViewModel, the Binder can no longer find annotations such as @Command, @NotifyChange, etc. This causes the ViewModel to stop working. Command and Init methods cannot be called properly. This problem is caused by the fact that Proxies usually do not retain method annotations and Binder only looks for annotations in the current class (the proxy). It can be easily fixed by making the Binder also look for annotations in the superclasses of the current class.
Following is an example of what we tried to do and then bumped into this issue:
The setup is ZK 6.0.0 + Spring 3.1.0 + Hibernate 3.6.
We want to create an aspect that advises all viewmodel methods annotated with @Command. That is why we have to make the viewmodels Spring-managed beans. We do this by setting the ZK-provided custom "desktop" scope and marking them with @Component (Spring annotation). In order to make aspects work, Spring creates proxies. So, the viewmodels are actually proxies. All is well until an annotated viewmodel method has to be called (@Init, @Command). ZK cannot find it.
That is when we started investigating. What we found is that the BinderImpl (org.zkoss.bind.BinderImpl) only searches for annotations in the current class. We fixed this by using a Spring utility class which has a static method that looks for annotations in the current class and all its superclasses.
These are some of the changes we made:
1. Inside BinderImpl.getInitMethods(Class<?> clz):
final Init i = m.getAnnotation(Init.class);
final Init i = AnnotationUtils.findAnnotation(m, Init.class);
2. Inside BinderImpl.getCommandMethod(Class<?> clz, String command):
final Command cmd = m.getAnnotation(Command.class);
final Command cmd = AnnotationUtils.findAnnotation(m, Command.class);
We applied the same logic for all annotations used in viewmodels.
The "fixed" BinderImpl is attached. However, in order to fix all the annotations, other classes have to be edited, too.