Blogger: Anne Thomas Manes
Paul Fremantle wrote recently about the new JSR181 annotation support added to the Apache Axis2 project. JSR181 allows you to add annotations to a Java class or interface, such as "@WebService" and "@WebMethod" to automatically convert the class into a web service and a method into a web service interface (portType). You can use these annotations in place of writing a services.xml configuration file or running utilities like java2wsdl and wsdl2java to generate the WSDL and services.xml configuration files.
For people that prefer the code-first development approach, annotations look like a wonderful feature. Just write your code, add a couple of annotations, compile, and presto -- you have a web service. What more could you ask for? Dennis Sosnoski wrote an excellent article explaining some of the advantages of the code-first approach. When used with build tools, such as Ant and Maven, the code-first approach also enables a lot of highly productive automation.
At some point I'm going to write a full-length rebuttal to Dennis's article explaining why I think code-first development is such a bad thing. His approach of adding a layer of abstraction by using a separate data binding framework (JiBX, in this case) to generate the WSDL and schema is a step in the right direction, but I still have a fundamental problem with generating schemas from code because it results in a proliferation of incompatible schema types -- increasing redundancy and complexity. Schema types should be the first-order sharable entities within a SOA initiative.
Annotation-driven development assumes code-driven development, and given my opinions about generating schemas from code, you can imagine that I'm not going to be a fan of annotations. But I have more fundamental concerns about annotation-driven development. For one thing, in order to compile a class containing annotations, you have to include a proprietary JAR in your classpath that is responsible for compiling the annotations. Paul touches on this point in his blog post:
[I could write a whole blog post about whether Java with annotations are really POJOs! After all, to compile a normal Axis2 POJO service I don't need anything Axis2-related in my classpath - I fix all that up later with XML descriptors. In this case, although the annotations are standard, I still need to have WebService specific JARs in my classpath to compile these "POJOs".]
Paul also goes on to explain about all the cool stuff you can configure using annotations. Basically, anything that you could configure in the services.xml file could also be configured using parameters in an annotation. But, of course, that means your annotations are no longer simple. And, they rapidly become proprietary -- because every framework supports a unique set of annotation parameters. Once you add annotations to a class, it's no longer a POJO.
I'm also really concerned about embedding infrastructure-related functionality into the application's source code. I'd much rather keep all that infrastructure-related stuff in a configuration file that can be edited without going back to the source code. Today you may want to expose the service using SOAP and WSDL -- but at some point down the road, wouldn't you also like to expose it using a RESTful HTTP interface or whatever the next latest and greatest middleware technology might be? Do you really want to go back to the source code to update an annotation?
Keeping infrastructure-related information in a configuration file is a good thing. Admittedly, configuration files have become a lot more complicated than the average developer would like. And no one really prefers to write in XML. But I don't think this move to annotations is any better. All we're doing is shifting the complexity, and in the process, we're reducing the flexibility of our code. I really think annotations are a step backward.