Welcome!

Linux Authors: Michael Sheehan, Lavenya Dilip, Ian Thain, Bruce Armstrong, Ellen Rubin

Related Topics: Open Source

Open Source: Article

Repel the Jedi Mind Trick by Turning to Enterprise Open Source Solutions

Enable a Module-Based Approach to Constructing Services

Now, Onto Building a Better Death Star
Everybody knows that the Death Star was destroyed by Luke Skywalker in Star Wars Episode IV: A New Hope. What they don't know is that another Death Star is being built using the latest and greatest Java frameworks. I guess you could say it's our lucky day. It's not easy constructing a monumental bringer of death out in the middle of nowhere. Droids, and many of them, must be gathered from across the galaxy to help in its construction. The system we'll be building for the Galactic Empire is an android (droid for short) provisioning system. I know that the Federation is in essence the Dark Side but the rates and benefits are outstanding. It doesn't hurt that there's free light saber training and laser target practice on Wednesday nights.

The key concepts that should be remembered throughout this exercise are:

• All of the services (modules) are POJOs that can be injected into any other module. These services could be a Web Service, data access service, common framework, business logic, or any number of other things required to make your application function.

• A service is a service is a service. Since our services are POJOs as well as Spring wired beans they can be exposed externally through any number of transport protocols. There are many frameworks that are tightly integrated with Spring that let you expose a Spring bean over HTTP, JMS, RMI, etc.

Let's look at the services that comprise our droid provisioning system as well as the key technologies that are used to bring it to life. Figure 2 shows the Maven modules of the droid provisioning application and their mapping to logical services with technology implementations.

This sample application will demonstrate injecting services (both through Spring and Maven), WSDL-first development using XFire, and the creation of a data access service layer using Hibernate. All of the corresponding code for this example can be found at http://dozer.sourceforge.net/example.zip.

Anatomy of the Parent POM
Maven provides the concept of a parent module that is key to project inheritance. This module lets you define common dependencies, organizational information, deployment information, and common plug-ins. A skeleton of the provisioning application's POM file is shown in Listing 1.

This listing shows a typical POM layout structure. This file defines project-wide dependencies, project metadata, and common plug-in configurations.

In a Galaxy Far, Far Away
Let's code. The first thing we need is a common module that can be used by all upstream modules. This core module is comprised of one service but could potentially hold many others. Our core service really doesn't do much except elaborate on the concept of injecting and reusing services. Here's our service defined as a Spring bean in our module's Spring context file:

<bean id="coreService" class="com.examples.droid.core.service.CoreService"/>

This bean references a Java class called CoreService that executes some core functionality.

The Maven configuration for this module is in Listing 2.

By defining our core module as a packaging type of jar Maven will compile our code, run unit tests, and package our classes into a jar file. The parent module inheritance is defined at the top of the configuration. No dependency version numbers are needed since they are defined in the parent. Let's see how this service can be used in sibling modules.

Springtime for Storm Troopers
Maven has the concept of dependency management to Spring's concept of dependency injection. At an abstract level the two are very similar and work hand-in-hand allowing for a reusable pluggable architecture. To add the core module as a dependency of another module we simply have to define it in our sibling module's POM file.

<dependencies>
    <dependency>
       <groupId>com.examples.droid</groupId>
       <artifactId>droid-core</artifactId>
    </dependency>
       ...
<dependencies>

The version for the dependency has been defined in the parent module. To use the service defined in the core module we'd simply inject it into the service defined in the sibling module's Spring context file.

<bean id="provisioningServiceImpl" class="com.examples.droid.ws.provisioning.ProvisioningServiceImpl">
    <property name="coreService" ref="coreService"/>
    ...
</bean>

To reference the Spring context defined in the core module it needs to be included in the list of context files that make up the system's Spring ApplicationContext:

String[] configFiles = new String[] { "spring/droid-core-beans.xml",
       "spring/droid-dao-provisioning-beans.xml" };
BeanFactory factory = new ClassPathXmlApplicationContext(configFiles);

We now know how to create a service module and inject it through Maven dependency management as well as through Spring's dependency injection. Let's create some more services while working up our layers of the architecture.

Darth Vader Wants His TPS Reports!
Darth Vader has seen the initial budget for the new Death Star and is having heartburn. He needs a way to run some queries on our android provisioning database. Darth is pretty savvy so he chose Hibernate for the application's object relational mapping (ORM) persistence framework. Using Hibernate tools to reverse-engineer the database lets us dynamically generate our ORM files and data access objects. Since we rely on this generated code before we compile our persistence module we can simply bind the Hibernate tool's source generation task to a particular Maven lifecycle phase. The Hibernate source generation is done at the generate-sources lifecycle phase in Maven by defining our plug-in's phase element as shown in Listing 3.

This task was done in a maven-antrun-plugin as an Ant task since when this article was written the Hibernate tool's Maven plug-in wasn't as robust as the Ant task. The Maven variable maven.compile.classpath lets you have all of the module's dependencies and transitive dependencies at your fingertips.

Typically, a real-world application will have a database running for these Hibernate tools tasks to reverse-engineer against. The example code uses a HSQL database engine to simulate this behavior. The source code to start-up, create, and populate the database can be found in the example application.

The data access service is defined in our Spring context file in Listing 4.

More Stories By Franz Garsombke

Franz Garsombke has been developing and architecting enterprise software solutions in Colorado for the last eleven years and is currently employed at Rally Software. Franz is a huge proponent of open source frameworks and is passionate about developing and delivering simple, quality, pragmatic applications. He is proud to be the co-founder of a Java Bean mapping framework (http://dozer.sourceforge.net) and can be reached at fgarsombke@yahoo.com or on his mountain bike.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.