Response to “Generalized data-access operations”

June 28th, 2010

Recently, a reader spotted a comment that I made on a different blog concerning generalizing data-access operations for inappropriate reasons. What follows was his email and my response:

Christian,

You made the following comment on this blog:

I’ve seen many examples similar to this that try too hard to fight an separation of concerns issue by ‘generalizing’ their data-access operations way too much.

Could you tell me why this approach is trying too hard?

Thanks,

Bob

Bob,

Here’s what I meant by that statement.

Data Access Objects (DAO) are used for primitive access operations against an abstracted data store (database, web services, RMI, etc, etc). Those primitive operations include insert, update, delete, query. I think the DAO should be limited to those operations, and only those operations, with an emphasis on very simple queries for the ‘query’ operation (e.g., “findByID”). The purpose of this reasoning is to keep the functionality on the DAO very focused on its limited responsibility. Adding methods such as “findByStreetAddressAndZip” or “queryForByAccountBalance” etc, prove to muddy the responsibility of a DAO.

However, those types of methods will most likely be necessary. But the context in which they are necessary helps illuminate the best place to put them. For example, in an architecture where the domain layer is nicely separated from the rest of the supporting software, and all domain logic resides there, those domain objects will need to retrieve data from a data store. Enter the repository pattern. (http://thinkddd.com/glossary/repository/) The repository pattern would provide the glue between the data store and your domain objects… you will find methods such as findByStreetAddres or findLastTransaction, etc, etc, but they will be completely related to the business logic and operations. These methods in the repository will provide a very explicit “seam” or contract between your business logic and the data store.

A lot of times the very subtle distinction between a “seam between business logic and data store” becomes muddied to mean “a seam between your software and data store’. This manifests itself when the repositories act as a seam between the business logic as well as the seam for the user interface. This is what leads to the explosion of “findBy…” “findWhenThisIsTrue”, etc methods. The user interface is constantly querying for data to display to the user, but is a repository the best place to put those methods? A repository is to act as a seam between the business logic and the data store, not the entire software (GUI) and the data store.

When the UI is also being fed by the repository objects, developers then cook up the reason for wanting to generalize the repository methods into findBy(Query). What this does is delude any sort of seam or contract you had with the business logic/data store, as well as open up the repository/data access to mean anything.

The fact is, retrieving data from a data store for the purpose of painting the UI is a DIFFERENT CONCERN than retrieving data from the data store to support the business logic. Coming to this realization can help simplify a design by putting the appropriate logic in appropriate parts of the architecture and keeping their responsibilities focused.

A simple example would look like this:
The domain module would contain repositories that implemented very specific methods for retrieving data from a data store in support of the domain operations. Generalized queries to support any UI functions would be disallowed. The domain layer would know nothing about the UI and what data it displays.

A UI module would have separate data-access classes specifically to support displaying data in the UI. Even if this approach *appears* to introduce some “duplication.” You may find folks take up crusades against this ‘duplication’ because they don’t understand the separation of concerns in this architecture. The *contexts* in which these objects are being used are completely different, therefore the objects should not be considered to be the same. The objects and data-access classes that support the UI will be able to change independently of the domain layer. They can be modified endlessly without any worry of breaking the domain. They can come from the same database/data store that the domain layer gets its data, or it can come from a completely separate database/data store in much larger applications (reporting or read-only DBs). This will allow your app to scale substantially better than if the UI and business logic operations/objects were all sloppily mangled together.

I realize parts of my explanation may need further examples or commentary, so please let me know where to expound if necessary.

Java static methods can be a code smell

February 15th, 2010

Response to “How to Mock Static Methods”

Definition of code smell (from Wikipedia):

“any symptom in the source code of a program that possibly indicates a deeper problem.”

In Java, static methods allow you to execute code at a “class scope” as opposed to an instance scope like member methods. This means, they rely on class-level variables (if any), parameters passed to the static method, or any other globally accessible data. They are NOT object oriented. An object has state associated with it and can be manipulated only through methods that implement the object’s “behavior.” Static methods do not operate on state, they are not object oriented, and in fact they are procedural.

Is this bad?

No. Although Java is object oriented, there will be times when procedural-like programming in Java is necessary and/or preferred. The real power in any object-oriented language is the ability to closely implement a model of real-life systems in code (see my post about object-oriented modeling). But even in the most hard-core object models, there will mostly likely be some glue code, or infrastructure code that will be implemented in a procedural style.

So if procedural-like programming in Java isn’t “that bad” and static methods are a form of procedural programming, are static methods bad?

Ahh… the answer isn’t as simple as a “yes”, or a “no” regardless of what you may read on other blogs But I could probably ramble on and on about why it’s really a decision that has to be made in context, so let’s keep this article focused by examining a set of statements that I encountered in “How to Mock Static Methods” from Michael Minella’s blog:

“Something that has become a fundimental [sic] piece of the language (all you need to do is look at the Apache Commons project to see that) is so bad that it must be avoided at all costs in the name of testing. Gosling (or someone on his team) put it in the language for a reason and to avoid those uses solely because your toolset doesn’t support the testing of it is nonsense. Time to get a new toolset.”

First, I’d like to point out that just because something has become a fundamental piece of a language doesn’t mean it’s “good” or something that should be done. Take a look at checked exceptions for reference. I recall EJB 1.x and 2.x becoming a “fundamental” piece of Java EE in the past, so look at that for reference too.

Second, although I do agree with Michael in theory that avoiding a particular language feature because your tools don’t support it is silly, his premise is focused on static methods. Avoiding static methods because your tooling doesn’t support them is NOT nonsense at all. In fact, the type of impedance caused by some of the good testing and/or mocking frameworks (of which Mockito is my favorite :) ) and static methods can be confidently identified as a code smell. This does not mean we should not do it, but we should exert extra effort to understand why we are doing it and explore alternatives if there are “deeper problems.”

There are at least two types of static methods that I would like to point out don’t usually show much impedance with testing/mocking frameworks. The first type is static methods used as utility methods, as those found in a lot of the apache commons libraries, or your own internal commons libraries. These are usually routines that are supportive of a particular method’s objective, and mocking/stubbing them out of a unit test wouldn’t make sense. They are part of the implementation, and should be tested as such. The second type is static methods used in place of constructors as Joshua Bloch showed in his book “Effective Java.” This use of static methods allows you to construct a new object using a method with a very descriptive name, among some other advantages. An offshoot of this second type of static method could include factory methods, but that would depend on context.

The most glaring code smell as a result of static methods and testing-framework impedance arises when a unit relies on a static method that performs logic outside the scope of the responsibility of that unit. In these cases, your testing framework will fight you because you cannot stub/mock the out-of-scope logic because it is “hardcoded” via a static method. This can be considered a “deeper problem” and is the focus of most blogs that tell you not to use static methods because testing becomes abnormally difficult or impossible. Changing the design approach to follow the Dependency Inversion Principle is one alternative. A better understanding of how to test the unit is yet another.

I assert strongly that in the case of static methods, the push-back you may get from your testing frameworks is indicative of a code smell, not that you need to try and find a framework that uses complex trickery with class loader remapping as a solution. One should be poised to evaluate the use and fundamental drawbacks of a particular approach in their design. Michael’s blog entry lends the reader to too easily assume a new tool/framework just because Java supports static methods and your current testing frameworks illuminate an impedance — in this case, the impedance reflects a code smell and some deeper, more critical thinking is required.

A “useful” model for object-oriented analysis and design

January 25th, 2010

Object Oriented Analysis and Design is certainly not new to the enterprise software workforce, but how is it actually carried forth in industry? Are software engineering groups reaping the benefits that OOAD claims?

Software systems these days are becoming more complicated than simple data-entry applications of the past. Many companies are intertwined with their proprietary software suites which allow them to compete at a level above their competition. With software becoming so valuable and tightly integrated with inherently complex business domains, what strategies are software engineers using to understand and cope with these domains, and are they working?

One strategy to cope with a complex business domain is to use a model.

Modeling complex systems is probably one of the hardest things to do as a software engineer. I think we’re more comfortable with exploring new technology, or learning new design patterns, and we don’t pay enough attention to learning the details of a domain much more than we need to “make it work.” Trying to use technology to hammer out a solution to a complex domain without understanding the domain ultimately leads to crappy software.

UML diagrams are not models. Nor are flow diagrams, sculptures, or code. A model is a set of concepts and understanding constrained to a given context. The concepts are chosen to illuminate the important parts and details of a problem context and avoid the non-essential ones. Dealing with complicated problems can be very difficult and overwhelming if the details are not well organized and conceptualized. Models can be explained by using UML, flow diagrams, or code, but buy themselves, they’re not the model.

The OOAD prescription tells us that an analysis model (http://en.wikipedia.org/wiki/Object-oriented_analysis_and_design) is a distinct and separate artifact from a design model. We use the analysis model to understand the domain (the “what”), and then we develop a separate domain model to implement it (the “how”).

Can two models like this solve the same problem? Sure, since a model is just a set of concepts, any number of models could probably solve the same problem. However, what happens in practice when you have two separate models: one in your head and one in the code? In my opinion and experience, both begin to deviate so much that the model in your head becomes misleading and the model in the code becomes lost. The analysis produces artifacts that focus on details that may be irrelevant when actually implemented in code, while the discoveries made while implementing in code (which can be incredibly important) rarely if ever get fed back into the analysis model. Instead, the developers ostensibly go down the track of developing a different model (if any at all) to compensate for unexpected details.

The solution is to use a model that both satisfies the analysis requirements as well as the design requirements. The model should focus on the problem domain and be applicable to the design of the code. If the model cannot be expressed properly in code, a new model should be chosen. An iterative process of learning more details about the domain, implementing them in code, and then going back to modify the model if the code is awkward will slowly generate a model that is useful and contains key knowledge of the domain. Changes to the model must imply changes to the code, while the reverse is also true: changes to the code imply changes to the model.

Coming up with a model that satisfies both understanding and coding requirements is hard, but certainly can be done. In the long run it can lead to systems that are easier to extend and maintain because the core principles of the domain are embedded in the code. The fact that the domain model (set of concepts) drives the design while the design feeds back into the model is very powerful and becomes a very practical approach to developing complex software.

Response to “Flaw in object-oriented modeling”

January 19th, 2010

I recently read a blog on the Intel Software Network describing the reduced execution flow readability in object-oriented systems that implement a domain model as being a “flaw” in object-oriented modeling.

I disagree completely, as a procedural (better execution flow readability, and the approach recommended by the author) approach is just a different animal compared to a modeling approach (which focuses on conceptual clarity, not execution steps).

The post (http://software.intel.com/en-us/blogs/2008/08/22/flaws-of-object-oriented-modeling/) was partly correct that modeling can reduce execution path redability, however it was incapable of providing a “flaw” in object-oriented modeling. My response was a good exercise in articulating the real reason behind object-oriented modeling: to use a model to manage complexity in business domains. See my response in the comments, but I’ve also reproduced it here.

Asaf,

Thanks for your post! It gives an excellent path to some vibrant discussions.

I would like to focus on the title of your post, and how I don’t believe the “flaw of object oriented modeling” is a flaw at all but rather two different approaches to programming with each one best suited for different contexts.

You say, “Object Oriented Modeling was invented to help developers manage the code”, but this is not entirely the case.

Modeling real-life systems has been around for many hundreds of years, though surely longer. Modeling can be found throughout many disciplines including engineering, architecture, mathematics, et. al. As mentioned above in previous comments, which I fully agree, modeling is an approach to problem solving that helps manage complexity in a given domain. Trying to implement a model in software can become difficult using languages that are not well-suited for modeling.  Object-oriented languages are a better fit for models because of their state+behavior (object) approach.  Procedural languages are not as good because they’re focused more on completing certain predefined tasks and not on capturing the concepts in the model. Object-oriented modeling is the implementation of a model with an object oriented language and can reap the great benefits of modeling. To say it was invented to “help developers manage the code” is entirely simplistic and misses the point of modeling in the first place.

On the other hand, you’re somewhat correct when you say modeling in software reduces the ability to follow an execution path. The reason is simply because modeling is focused on concepts and behavior, and not a predefined, task-oriented, series of steps. Therefore,  the reason you put forth for a “flaw in object modeling” is no flaw at all. It’s a completely separate approach for solving a problem. If the problem has to do with mathematics and physics, no doubt you would model it. If the problem has to do with a complex business domain, a model will help manage all of the complexity found in such a domain. If your problem is writing device drivers or embedded systems software, a procedural approach probably would be more appropriate.

Can you write device drivers using a modeling approach with an object-oriented language? Probably. But it might be overkill, muddy the tasks taken to perform the driver’s functionality, and obscure the execution path.

Can you write complicated business logic in a purely procedural manner? Probably. But the software would end up looking like a monstrous tangle of functions without key active elements in the domain clearly conceptualized, and maintenance would be a nightmare as a better understanding of the domain emerges.

Your post must assume that the people who argue ‘for’ object-oriented modeling argue for it as a solution to every problem. That is most certainly not the case. With the understanding that object-oriented modeling, or rather modeling in general, is appropriate for certain cases, your post demonstrates no “flaw” in object-oriented modeling at all. Either focusing on concepts or focusing on tasks is an appropriate approach given the context.

Thanks again for your post.

Christian Posta

Why should we ‘waste time’ on unit tests when we could be writing functionality?

June 12th, 2009

Our goal when writing code is to write ‘high-quality’ code, not just hack together what appears to work and moving on to the next set of functionality. When writing ‘high-quality’ software, we must test and verify that our code does what we wrote it to do and to properly handle conditions that are outside the scope of the specs (boundary conditions). Doing so will make our code more robust and reduce the likelihood of bugs being discovered later on in the development process. As you should already know, the cost of fixing bugs dramatically increases further out in the development process. If a bug is found, we can more confidently change/alter the modules to fix the bug knowing that our previously working functionality still works (by running the unit tests). If we had no tests to act as a verification of working code, we would be much more likely to introduce new bugs with our ‘bug fixes’ and not notice them.

Additionally, writing unit tests increases code quality by improving maintainability. Maintainability is just as important as getting the functionality to work because we must be able to change the software as it adapts (without breaking working functionality) and we (other) developers must be able to read the code. What is it worth to have a heap of unreadable, unmaintainable code that must be changed/fixed? Unit tests provide a way to quickly understand how the code is supposed (or not supposed) to be used. And again, it also provides that backstop against which we can verify whether or not functionality has been broken by our changes. Moreover, in an agile development team, code is ‘collectively’ owned, i.e., no one person truly owns the code; everyone should be able to read, understand, and modify the code. Unit tests greatly help a person who’s trying to read the code to make modifications confidently.

Unit testing also helps improve the design of the code. As our tests are verifying the internals and externals of the unit of software usually with mock or stub objects, we must design our code to be decoupled from the rest of the system. This decoupling is usually done by ‘programming to abstractions’ or interfaces. We cannot test the internals of code that does not allows to swap out mock/stub implementations for
dependencies. Writing testable, decoupled code also improves design and thus code quality.

If we as professionals do not strive to improve code quality and integrity of the systems we deliver, what better are we than any offshore code sweatshop producing crap at 1/20th our bill rate? The answer’s simple. Take pride in your profession and strive for quality code or get of of this industry (you’ll be forced out by offshoring anyways… only then, you’ll be crying for government bailouts… be proactive).

CRUD example: Ext-GWT + Spring + Hibernate

February 26th, 2009

I am planning a series of posts  that walk a reader through building a simplistic application using Ext-GWT as the choice of technology for the user interface, Hibernate as the ORM, HSQLDB as the backend, and the Spring Framework to manage all of the application objects and bring everything together. I’ve chosen these technologies, but they are not the only options. They are all open source/freely available.

What is the Spring Framework?

The Spring Framework is a modularized framework that makes working with Java EE APIs easier. Spring also provides a component container that is independent of any Java EE application server. This means you can run your applications (and test them) without being tied to any vendor-specific application servers, but enjoy enterprise-level services such as declarative transactions, internationalization, and resource handling. At its core, Spring provides a dependency injection container that allows your application objects to be wired up at run time instead of hardcoding dependencies at compile time. A simple example of dependency injection:

public class Foo {
  private Bar operation;
  public Foo(){
    operation = new Bar();
  }

  public void doFoo() {
    operation.doOperation();
  }
}

As you can see, the class Foo depends on class Bar. What if we wanted to change the behavior of Foo’s dependency on Bar? We would have to replace the Bar member with a Bar2 member, and replace the call to “new Bar()” in the constructor with “new Bar2()”. What if, however, Bar was an interface, and classes that implemented Bar were injected into Foo? Foo would have no idea what Bar’s implementation is (wouldn’t have to explicitly call “new Bar()), and it wouldn’t even know where it came from. All Foo would know is that it has a dependency on Bar and uses it. Example:

public class Foo {
  private BarInterface operation;

  public void doFoo() {
    operation.doOperation();
  }
  public void setOperation(BarInterface op){
    this.operation = op;
  }
}

Now all you have to do is inject the appropriate implementation of BarInterface into Foo, and Foo will run as desired. The Spring Framework handles this type of “wiring up” of the components in a declarative fashion.

Why would you want to externalize “wiring up” your application components to a framework? Well, first, think of the “wiring up” of your application as “assembling the components together so that it can run.” The application, once it’s assembled and running, is a very different concern than the configuring and assemebling that went into it. For example, assembling the desk you just bought from a furniture store is a completely different concern than actually using it to store pencils and papers once you’ve completed assembly. Identifying and separating concerns like this helps to modularize and decouple the application into manageable and maintainable pieces.

Second, Spring does a good job of getting out of the way and not requiring the user to depend on the framework. In other words, your application objects do not need to use any org.springframework.* classes if they do not want (or need) to. Spring will allow your application objects to be completely unaware of the dependency injection container.

Our example

For our example, we’ll modify the reference “Mail” program that ships with Ext-GWT, and give it the functionality of creating, reading, updating, and deleting (CRUD) emails from the ficticous “mail system” that we’ll implement.

Before continuing, however, I highly recommend the reader download and play around with the Spring Framework. There are great tutorials online, and the reference manual is excellent too.

SOLID Object Oriented Design Principles

January 29th, 2009

I am working on the next Ext-GWT blog, but in the interim, I would like to share an awesome podcast that I found at Scott Hanselman’s blog. He interviews Robert C. Martin (author of a few excellent agile, code cleanup, and object oriented design books) who dives into great explanations of the “SOLID” (Single Responsibility, Open-Closed, Liskov Substiution, Interface Segregation, and Dependency Inversion) Principles of which every object-oriented developer should be aware! Listen to the podcast at Scott’s blog.

Untangling GXT Store/Loader

December 27th, 2008

The Ext-GWT (GXT) library uses a “loader-store” functionality to handle manipulating UI models (or domain objects) and binding them to GXT widgets. The Ext team has posted a simplistic overview document of the “loader-store” mechanism at their Helpcenter. The focus of this blog entry will try to build upon the initial documentation provided by Ext and explain step-by-step how to use the loading mechanism to load your models from a remote source and populate a GXT store.

The pre-requisite expectations before diving into this entry is a cursory understanding (browsing through the GXT reference apps is enough) of the loader-store API and having read the Helpcenter docs regarding the loader-store functionality. I think once you’ve seen it in action (in the sample apps) and recognize that there is some untangling to be done, you’ll be ready to dive into this entry :)

Store

The GXT Store API (com.extjs.gxt.ui.client.store) provides classes generally oriented around the concept of a “store” or a central storage place for your UI or business models. From the Store API documentation: “The store class encapsulates a client side cache of ModelData objects which provide input data for components.” I guess you could think of a store as a collection (java.util.List?) of models which can fire events when properties of the store change and can track changes to models.

The Store class is marked abstract; you may want to pay more attention to specific types of stores: the ListStore and TreeStore classes. ListStore is used to populate widgets that use lists (think of tables, grids, combo boxes, data lists, etc) and TreeStore is for tree-based widgets (the Tree and TreeTable widgets).

As I mentioned, widgets can display the models from the store that backs them. When a widget is backed by a store and a model in that store gets updated, the widget will also automatically update. For example, if a Grid widget is backed by a ListStore and one of the columns is displaying the “name” property of the store’s models, and some one (programatically or otherwise) changes the value of “name” in one of the models, the “name” value will also automatically change in the Grid.

How does a store get populated with models? You could call ListStore.add(Models) or TreeStore.add(Models) for trivial purposes… or… you could use the “loader” mechanism.

Loader

A loader does exactly what you might be thinking that it does. It is used to load models into a store, generally from a remote source. Think of a loader as an object who’s responsibility is to retrieve a payload from a remote location, read the payload, and then tell the store to load itself with the retrieved data.

You have the option to create a new store and give it a loader. When a store has a loader, it will use the loader to load the models. See the following snippet for instantiating a store with a loader:

    BaseListLoader loader = new BaseListLoader(proxy);
    loader.setRemoteSort(true);

    ListStore store = new ListStore(loader);

Hopefully you’ve gotten the connection between the loader and the store. If not, please leave a comment asking a specific question. Let’s move on.

As I mentioned above, a loader retrieves a payload from a remote source, reads the payload, and then tells the store to populate itself with the models that the loader read from the remote source. The loader is flexible enough in that it allows you to inject the collaborator that will be responsible for both retrieving the remote data and then reading it. You will notice that the following are both legal constructors for creating a loader:

BaseListLoader loader = new BaseListLoader(proxy);
BaseListLoader loader = new BaseListLoader(proxy, reader);

Proxy

The proxy object in the above constructors is of the type DataProxy. This object is what is used to retrieve the data from the remote source. You can write your own collaborators to load data from a remote source, but the following are the default implementations provided by the GXT framework:

  • HttpProxy - A concrete DataProxy that retrieves data using a RequestBulder instances
  • MemoryProxy - A DataProxy implementation that simply passes the data specified in the constructor to the reader when its load method is called
  • RpcProxy - DataProxy implementation that retrieves data using GWT RPC
  • ScriptTagProxy - An implementation that adds a JavaScript to the page responsible for loading (please correct me if
    someone has a better way of explaining this implementation.

I will be demonstrating the use of the RpcProxy which uses GWT’s RPC mechanism to retrieve data from a remote source. The basic idea is to instantiate a RpcProxy object which knows how to connect to and retrieve data from a remote location. After filling in the appropriate methods, the loader will use it to populate the store. See the following example of instantiating an RpcProxy:

    RpcProxy proxy = new RpcProxy() {
      @Override
      public void load(Object loadConfig, AsyncCallback callback) {
        service.getPosts((PagingLoadConfig) loadConfig, callback);
      }
    };

The code snippet above is from the PagingGridExample from the Examples demo. Notice that in the load method (line 3) the GWT-RPC proxy is called. A loadConfig object does not have to be one of the parameters to your RPC service, but in this example, it’s used to supply sorting parameters (server side).

Putting it all together

Hopefully, I’ve shed some light on the three components necessary to put together communication with a remote resource and how the store uses the loader, which uses the proxy, to get models into the store.

To put everything together, we’ll take a look at the com.extjs.gxt.samples.client.examples.grid.PagingBeanModelGridExample.java class as reference. See the code relevant to setting up the grid’s store below:

    RpcProxy proxy = new RpcProxy() {
      @Override
      public void load(Object loadConfig, AsyncCallback callback) {
        service.getBeanPosts((PagingLoadConfig) loadConfig, callback);
      }
    };

    // loader
    BasePagingLoader loader = new BasePagingLoader(proxy, new BeanModelReader());
    loader.setRemoteSort(true);

    loader.load(0, 50);

    ListStore store = new ListStore(loader);

This snippet is taken from line 55-71 from PagingBeanModelGridExample.java. Everything has been discussed, except for the BeanModelReader() object that is passed to the loader. In this case, the BeanModelReader class is used to read the results of the GWT-RPC call that returns pojo model objects. The reader then wraps the pojo’s as BeanModel classes.

If I’ve left something out, or something I’ve said is unclear, please leave me a comment, or feel free to email me: christian.posta@gmail.com

Using Apache Maven with Ext-GWT (part II)

December 3rd, 2008

Although the gwt-maven-plugin from codehaus is going through the merge with the gwt-maven plugin from Google Code, I wanted to share with you how building the Ext-GWT mail application with the gwt-maven-plugin from codehaus is a little easier. Please find the code for this second part here

You’ll notice the POM file is a little less verbose with regard to configuration and additional plugins (the plugin used to unpack the native GWT lib). There are more default plugin configuration parameters also.

Run a mvn install at the root of the code distribution to compile into a war file. Note that your MAVEN_OPTS environment variable should be set to increase the memory of the JVM.

Creating eclipse project files is simple also. Although I would recommend getting the m2eclipse plugin for Maven projects, you can generate eclipse plugin files by running the following maven command from the root of the code distribution (the directory where the pom.xml file exists):

mvn gwt:eclipse

Stay tuned for more details about using this plugin as the codehaus and Google Code plugins merge!

Using Apache Maven with Ext-GWT (part I)

December 1st, 2008

Apache Maven is a popular project-management tool that allows you to model your projects in XML and then streamline the development lifecycle by taking advantage of dependency management and convention over configuration. I use Maven for all of my new projects, and I have had the chance to use Maven to manage my GWT projects. The purpose of
this blog entry is to demonstrate to the GXT community how to get Maven up and running to manage one of their projects.

First, I’d like to point out that the folks over at Sonatype have put together a terrific book detailing the use of Maven. I definitely recommend browsing through the first few chapters to get a better understanding of what Maven is, how to use it, and examples of Maven projects. Sonatype also put together the m2eclipse plugin for integrating and managing your Maven projects in Eclipse. Point your Eclipse update manager to http://m2eclipse.sonatype.org/update/

Second, I’d like to thank the Charlie Collins and the creators of the gwt-maven plugin. They did a good job of putting together an easy-to-use plugin for GWT projects. I use the gwt-maven plugin in the example that follows.

I’d like to also mention that the purpose of this blog entry is not to convince anyone to use Maven. I’ll leave that to the Maven documentation. This blog entry is simply an introduction to using Maven with GXT/GWT. There are plenty of other build mechanisms out there that could arguably be used in a comparable fashion. For example, the developers of GXT use Apache ANT for their build environment. Combining ANT with Apache IVY provides a suitable alternative to some of the features discussed in this blog.

Getting Started

To get started, download the code for this project. It is simply the Ext-GWT mail reference application with a Maven POM and directory structure used to build the project with Maven. I recommend you browse through the code briefly to get an cursory understanding of the directory structures. We will start by examining the POM for the project, so you may want to get familiar with that too.

Building the project

You’ll need to have Apache Maven installed properly before you can build the project. Go to http://maven.apache.org/ to download Maven.

After downloading the source code and extracting it to a suitable directory, you can kick off the build lifecycle by typing the following Maven command from the directory that contains the pom.xml file:

mvn install

Maven will do its thing to compile, run tests, and package the project; the build should end succesfully. Maven requires access to the internet to download dependencies, so verify you’re connected.

After a succesfull install, look in the “target” directory to find the “mail.war” file.

To run the project in GWT hosted mode, type the following command at the prompt:

mvn gwt:gwt

NOTE: unfortunately, running the hosted mode with the “gwt” prefix no longer works. A competing gwt maven plugin fromcodehaus has caused a clash with the “gwt” prefix. See the last section of this post for more.

The pom.xml

At the root of the project is the Maven POM file. This file is the Project Object Model that is used to model the project including the Maven plugins and project dependencies. For more info on a Maven POM, see the reference documentation. We’ll step through the pom.xml file that comes with this project to explain each of its materially important xml entries.


	4.0.0

	com.extjs.samples
	gxt-mail
war
	1.1.3

	GXT Mail compiled with Maven

This section contains the basic Maven POM coordinates to identify the project. Nothing too special about this part, but it’s necessary.


		1.5.2
		com.extjs.gxt.samples.mail.Mail
		index.html
	

This section contains project-specific properties, including the version of GWT to use, the name of the GWT module to compile, and the name of the host html page for the GWT module. If you’d like to use this POM to compile your own GWT project, you can replace these project properties to fit your own specs.



			gwt-maven-plugins
			
                http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/
            
		
	

At the moment, gwt-maven has its plugins hosted at their repository at Google Code. This section contains the plugin repository for gwt-maven.

	
		
			com.extjs
			gxt
			1.1
		
		
			com.google.gwt
			gwt-servlet
			${gwtVersion}
			runtime
		

		...

		
			junit
			junit
			4.1
			test
		
	

This section models the project’s dependencies. You’ll see that the Ext-GWT library, the GWT jars, and other ancillary dependencies are listed here. NOTE: The GXT jar on the Maven Central Repository is outdated. See the section below on how to manually install the jar to your local repository.

	
		mail


		...


	

This section is probably the most important as far as configuring Maven to compile GWT sources (actually, the stuff I left out of this section is the most important). We look at the plugin configuration below, but I wanted to point out that the “finalName” element contains the name of the war file that will be produced. If you do not define a “finalName,” the project name and its POM coordinates will be used to derive the war filename.

Each of the following four sections will be the plugins described in the “plugins” section.


				com.totsp.gwt
				maven-googlewebtoolkit2-plugin
				2.0-beta25
				
					INFO
					
						${gwtModule}
					
					${gwtModule}/${gwtHostPage}


					false
					-Xmx512m
					${gwtVersion}
				
				
					
						
							mergewebxml
							compile
							test
						
					
				
			

This is the gwt-maven plugin declaration and its associated configuration. Lines 5-15 specify the configuration parameters including the GWT compile target (which is our GWT module name), the run-time target (including the host page), and finally the version of GWT to use.

The “executions” element enumerates the plugin goals to run:

  • mergewebxml - this goal takes the web.xml file in the src/main/webapp/WEB-INF/ directory and merges it with the GWT module xml (*.gwt.xml) file. It will automatically generate a servlet mapping in the web.xml file for each servlet defined in the GWT module xml file.
  • compile - this goal invokes the GWT compiler on the source code
  • test - this goal invokes the testing framework (JUnit) on the project tests if they exist (there are no tests defined for this project)

The gwt-maven plugin contains other goals. See the documentation for more details.


				org.apache.maven.plugins
				maven-dependency-plugin
				
					
						unpack
compile
						
							unpack
						
						
							
								
									com.google.gwt
									gwt-dev
									${gwtVersion}
									${platform}-libs
									zip
									false
								
							
						
					
				
			

Since the GWT libraries are specific for each platform (windows, linux, mac, etc), Maven will need to decide which platform we are using (using the “profiles” entries below) and then use the maven-dependency-plugin to unpack the correct jar for the gwt native libraries. This is the “automatic” mode for unpacking the platform jars. See the documentation for more details.


				org.apache.maven.plugins
				maven-war-plugin
				
					target/web.xml
					.gwt-tmp/**
				
			

Since we use a “merged” web.xml file, we’ll need to tell the maven-war-plugin which web.xml to use. Othewise, it will just use the one in src/main/webapp/WEB-INF. We can also choose to exclude some of the gwt temp files.

Another note about the web.xml file and the mergewebxml goal. The web.xml file in the src/main/webapp/WEB-INF directory DOES NOT contain any of the servlet mappings for the GWT RPC servlets; the mappings will be generated automatically by mergewebxml. The reason for this is the plugin also uses the web.xml file in the src/main/webapp/WEB-INF directory for the hosted-mode tomcat. The plugin automatically addes the “GWTShellServlet” servlet to properly serialize objects in hosted mode. If you also have your own GWT-RPC servlets mapped, it doesn’t work properly in hosted mode. This is something I’ve inquired about at the gwt-maven project web page.


				org.apache.maven.plugins
				maven-compiler-plugin
				
					1.5
					1.5
				
			

For the last plugin, we tell the javac compiler to use a source and target of Java 1.5



			gwt-dev-windows

windows

			
				true
				
					windows
				
			
		

		...

			gwt-dev-linux

linux
			
			
				false
				
					linux
				
			
		
	

Finally, we use Maven activation profiles to let the project know which platform on which we’re developing. The activation takes place if the “activation” element’s entries are true (for example, if the platform is of the “windows” family, the property “platform” will be usable with the value of “windows”).

Deploy

After running the “mvn install” command, browse to the “target” directory to find the mail.war file. Deploy this file to your application server and browse to (for example) “http://hostname:port/mail/com.extjs.gxt.samples.Mail/”.

Installing GXT jars locally

At this point, the GXT jars are not updated on the Maven Central Repository. You may want to install the jar into your local repository so that you can reference it from the POM. Follow these steps to install into your local repository:

  1. Download the GXT library
  2. Unpack the GXT library to a suitable directory
  3. From the directory that contains the “gxt.jar” file, type the following command:
    mvn install:install-file -Dfile=gxt.jar -DgroupId=com.extjs -DartifactId=gxt -Dversion=${version.number}
    

    where ${version.number} is the GXT library version number.

After installing the GXT library locally, you can change the dependency entry in the POM:

	
		
			com.extjs
			gxt
			${version.number}
		

		...

gwt-maven-plugin at mojo.codehaus.org

A new project has evolved over at the mojo.codehaus.org website that will provide a GWT plugin. The owners of the code at the Google Code’s gwt-maven project (the plugin used above) have decided to work with Nicolas De Loof at codehaus to merge the two projects.

At the time the codehaus gwt maven plugin was uploaded to the Maven central repository, the goal used in the Google Code’ gwt-maven plugin to run the hosted-mode GWT shell no longer worked. Use the following goal (with the complete plugin name) to run hosted mode with the gwt-maven plugin:

mvn com.totsp.gwt:maven-googlewebtoolkit2-plugin:gwt

I encourage any of you interested to pay close attention to the Maven project at codehaus. Although it is not as mature as the Maven project at Google Code, it does perform some common GWT tasks (compile, eclipse configs, etc) and from what I can tell from my initial investigation, it may end up being much easier to use.