Friday 9 December 2011

Eclipse error: using @Override on method implementing an interface method

@Override on a method implementing an interface is not allowed in Java 5, but is allowed in Java 6+

STS 2.7.2 by default seems to set projects up to be Java 1.5.  If you would like to use Java 6, right-click on your project->Properties->Java Compiler and change Compiler compliance level to 1.6.  After a project rebuild the error should be gone.

Thursday 8 December 2011

STS: Updating Namespace List in Spring Bean Configuration Files (Maven)

STS provides a nice wizard for constructing Spring configuration files.  Right click on Project or destination directory, then New->Spring->Spring Bean Configuration File.

You can pick XSD namespaces from a list, which saves cut-and-pasting them from an another configuration file, ripping them off a blog or - heaven forbid - trying to write them yourself.

You may find the namespace list is intitially empty.  To fix this add desired dependancy jars to your Maven pom.  [May be necessary: right click on project->Maven->Update Dependencies].  If your config file is already open, close and re-open it and then click on the "Namespace" tab to select from the namespace list:


Sunday 4 December 2011

Java and Spring Annotations

Java annotations are not inherited, unless the annotation type is annotated with @Inherited.

However, from the @Inherited Javadoc:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

It seems Java ignores annotations on implemented interface method in order to avoid multiple inheritence issues: http://stackoverflow.com/questions/4745798/why-java-classes-do-not-inherit-annotations-from-implemented-interfaces

Now let's consider Spring's @Transactional:
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactionalannotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

But Spring Security's @Secured is different.  Most the documentation shows the annotation on the interface class methods.  In my tests @Secured works on concrete classes and the interfaces and regardless of whether JDK or CGLib proxies are used.  This solution appears to be superior to the @Transactional solution.  It must reflect not only the methods in question but also discover their interfaces and reflect those, etc, etc...  Clearly there's a performance impact, but this seems like a better solution.

Having differing solutions is annoying, confusing and error-prone.