Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Thursday, February 10, 2005

Streamlining HiveMind Module Deployment Descriptors

We often complain about the verbosity of J2EE XML descriptors. The HiveMind descriptors are better, but there's still a lot of typing.

One thing that struck me is that there's a lot of needless duplication of package names. Often the package name matches the module id ... and yet, you'll retype the package name for each service interface and each class.

So ... what if HiveMind just assumed that simple interface and class names were in a specific package? Also, what if the module id and the package name aren't the same?

What I've done it to add a package attribute to <module> (which defaults to the module id). I modified a lot of code to make use of the package name when a reference to an object type shows up (and, in fact, improved the code by adding a resolveType() method to the Module interface). Literally, if the class name as is doesn't exist, then a second try (prefixing the class name with the package name) is made.

This simplifies the examples module descriptor:

<?xml version="1.0"?>
<module id="examples" version="1.0.0" package="org.apache.hivemind.examples">
    <service-point id="Adder" interface="Adder">
        <create-instance class="impl.AdderImpl"/>
        <interceptor service-id="hivemind.LoggingInterceptor"/>
 . . .

What's nice is that you can use "relative" class name, such as impl.AdderImpl, which is really org.apache.hivemind.examples.impl.AdderImpl. See what I mean about less typing?

Perhaps we'll go further in the future ... for instance, maybe <service-point> should assume that the interface matches the service point id?

There will be cases where you really want to support many different packages in the same JAR. You will then either type fully qualified class names, or split your JAR into multiple logical modules using <sub-module>.


Mauro said...

There are some plans to use ejb3 anottations as a solution?

Like anottations of persistence that will be usefull to change the persistence ???

Like a anotation implementation used by HiveMind?

Howard said...

Huh? Where did you get EJB annotations from? We would define Tapestry annotations to represent Tapestry concepts. And what HiveMind annotations are you talking about? HiveMind is descriptor driven ... and its not clear to me how to make it annotation driven ... perhaps annotation enhanced.

Mauro said...

Sorry my english is not so good
I now that hive mind is descriptor drived like sping and Hibernate

But in EJB3 Early Draft 2 there are to specifications one for persistence and another for the rest. Hibernate has an
alpha implementation of annotations specifications for persistence mechanisms that culd be used instenad of mapping files...Another mechanism like Cayene for example culd have in futere his Anotations implementation so my domain objetcs culd be persistence mechanism agnostic.

They will have a persistence menager (Facede) that culd be used by your aplication and some annotations that
if implemented by Spring and Hivemind culd be used by my controller class so they culd be lightway conteiner agnostics for example....


knut said...

That's a cool idea! On the downside a rename refactoring in Eclipse won't be able to update the references in the module descriptors :-(

Paul said...

In 1.1.1 this doesn't seem to work unless I fully qualify the interface on the service point, ie. if my service is defined as <service-point id="Adder" interface="Adder">, I get a "There is no service point for interface org.apache.hivemind.examples.Adder" when I call getService(Adder.class) from a Registry. If I change the service definition to <service-point id="Adder" interface="org.apache.hivemind.examples.Adder"> I get the service from the Registry without any problems.