I was doing some Java philosophizin' a couple of days ago. The flotsam and jetsam of my thoughts were annotations and deployment descriptors…
When EJB 3.0 pitched annotations as a replacement for the deployment descriptor, I relished the idea. It was right in line to what Xdoclet does and I thought that EJB 3.0 was moving in the right direction. I later realized that this wasn't such a great idea after all.
Replacing deployment descriptors with annotations defeats code reuse. One class becomes locked to its first design such that if you later decide to reuse that class in another project, you'd have to violate the DRY (Don't Repeat Yourself) principal. You would have to copy and paste the class into your new project. On top of that, you’d then have to rewrite the annotations for the class in your other project.
So, are deployment descriptors still the way to go? Well, not the way they have been done. In EJB 1.0, deployment descriptors were actual Java classes. This was, obviously, not an elegant solution, but EJB 2.0 deployment descriptors weren't heavenly either. In EJB 2.0, deployment descriptors consisted of huge XML files (even for medium sized projects). Most likely, the use of EJB and its massive descriptors gave rise to designers’ use the term “XML Hell”.
The way to go…? Well, it may be to use an idea that Hibernate seemed to have right for ORM (object-relational-mapping) – one deployment descriptor per class. This has more advantages than annotations, Xdoclet tags, and huge “XML Hell” descriptors.
Perpetuating my Java philosophizin' reverie, I began to imagine the great implications of using one deployment descriptor per class and my thoughts drifted onto other applications for which deployment descriptors might be used.
During a moment of clarity, I came up with something I call “films” – deployment descriptors for various applications that are set up as specifications so that you can use them for various applications and application servers. To highlight what I am talking about, let’s say that we have a class called Customer and it has a property called firstName.
public class Customer {
private String firstName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
}
This simple POJO can have multiple descriptors. For example, if we eventually decide to store an object that came from this class onto a database, we can create an ORM deployment descriptor with a file name like customer.orm.film.xml:
<orm>
<property name="firstName">
<primary-key/>
<column name="FIRST-NAME"/>
</property>
</orm>
It would be best if this “film” was regulated as a spec so that all ORM manufacturers would have a common descriptor. This would also benefit the write once, run anywhere evangelists out there.
We can also create a validation “film” for this class so that it can be replaceable and changed without structural changes to the POJO. This one would be named something like customer.validation.film.xml:
<validation>
<property name="firstName">
<not-null/>
<not-blank/>
<regex value="[A-Z][a-z]"/>
</property>
</validation>
The nice thing about having a validation “film” is that this descriptor can be used by your web framework, your ORM system, your Swing app, your XML schema representation, and Webservices. One validation descriptor can go a long way. Perhaps the biggest advantage to something like this is database, class, and object synchronization. In other words, you will not land in the quagmire where your bean property accepts unlimited characters but your database field only accepts 20 characters.
We don’t have to stop there either… should you desire, we can have a “film” for IoC bean containers, like Spring, that you can reuse with, perhaps, JavaSpaces. Spring already has awesome deployment descriptor functionality, but if it were to be broken up per class, I believe Spring things would be easier.
<ioc type="all">
<bean id="CustomerBean" class=”Customer”>
<property name="firstName">
<value>Stan</value>
</property>
</bean>
</ioc>
The IoC bean containers can then be used by other “films” like descriptors for object based web frameworks. Imagine that – a common descriptor for all web frameworks! ;) The web framework would also be able to use the validation “film” discussed earlier.
<web>
<property name="firstName">
<renderer>
<class>...</class>
</renderer>
<converter>
<class>...</class>
</converter>
</property>
<action-property name="create" id="CustomerBean">
<navigation-rule>
<from-view-id>/customer/create.jsp</from-view-id>
<navigation-case>
<from-outcome>Success</from-outcome>
<to-view-id>/customer/createsuccess.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>Failure</from-outcome>
<to-view-id>/error.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</action-property>
</web>
Those are just a few examples of what “films” can do. Other applications for “films” could be as varied as aspect descriptors, descriptors specific to your application server, descriptors for your Swing application, descriptors for JNDI, descriptors for Webservices, descriptors for transactions, descriptors for thread-management, and on and on.
I am very interested in your opinions on this idea. I think this would be great as a JCP spec so as to offer consistency with deployment descriptors. If there is already something like this out there, let me know.
