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"/>
    </service-point>
 . . .

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>.

3 comments:

Unknown 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.

Knut Wannheden 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 :-(

Anonymous 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.