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.

Getting started with Ext-GWT: The Mail reference application

November 14th, 2008

For this entry, being the first, I would like to help the Ext-GWT community (especially those newly introduced to the framework) grasp a firm understanding of the reference “Mail” application, specifically the MVC structure found in this app. I have found that understanding these reference applications (especially the MVC) goes a long way toward using the Ext-GWT framework in a manner for which it was intended.

Some pre-requisites

  • Familiarity with the MVC design pattern
  • Knowing how to put together a Google Web Toolkit application. See the GWT Documentation, as it is very good.
  • Having downloaded the Ext-GWT (GXT) framework from Ext JS. I will be using the code from the gxt-1.1.3 release.
  • A brief perusal of the GXT code base and mail application source code

Also, see the Ext-GWT documentation center for more details on setting up a project using the framework. Darrell Meyer, the lead developer for the framework, has put together some very good tutorials for setting up your workspace in Eclipse and what requirements are necessary for getting a project up and running.

Stepping through the source structure

Let’s get started by stepping through the source code to get an understanding of where everything is, what its role is, and finally, to transition us to the MVC discussion.

To see the actual source for the reference application, move to the root of the GXT distribution (we’ll call that GXT_HOME) and navigate to GXT_HOME/samples/mail. From there you can click into the ’src’ folder and see the directory structure for the app, com/extjs/gxt/samples/mail. You’ll notice that the structure follows the recommended GWT application structure.

com/extjs/gxt/samples/mail

/client/
/public/
/server/
/Mail.gwt.xml

You’ll find the GWT application Module XML file here. If you understand the GWT module XML document, what it does and why it’s used, you’ll see that for the mail reference application, there isn’t anything too complicated:


  

  
  

From line 2 we can see we inherit a GXT module named ‘Resources’. From line 4 we see that there is a GWT-RPC servlet defined for the path ‘/service’. Lastly, we can see from line 5 that our entry-point class is com.extjs.gxt.samples.mail.client.Mail.

/com/extjs/gxt/samples/mail/client

/model/
/mvc/
/widget/
/AppEvents.java
/Mail.java
/MailService.java
/MailServiceAsync.java

This is the folder for our GWT/GXT client-side source. The GWT entry-point class, Mail.java, is here along with our GWT-RPC MailService (MailService.java and MailServiceAsync.java). There is also another class, AppEvents.java, that is used to enumerate the different application events that can be passed to our mvc controllers (discussed below).

/com/extjs/gxt/samples/mail/client/model

/MailModel.java

This is the only one model object defined for this application. Of course, in your applications, you will probably define quite a few more. I say defined because there are other client-side models used for this application: MailItem and Folder. These models are defined in the GXT Resources module (see the Mail.gwt.xml for how the Resources module is included).

The models described here, and used on the client side, should (in my opinion) be used only for client-side organizing of data structures (grids), forms, and other user-interface components (trees, tables, combo boxes, etc). These should not be the same domain objects used in your business-layer. GXT is a client-side, user-interface framework, and models defined for the client side should serve client-side purposes.

MailModel.java source code:

public class MailModel extends BaseTreeModel {

  private Folder inbox;
  private Folder sent;
  private Folder trash;

  public MailModel() {
    inbox = new Folder("Inbox");
    sent = new Folder("Sent Items");
    trash = new Folder("Trash");

    List items = TestData.getMailItems();
    int count = items.size();

    List inlist = new ArrayList();
    List sentlist = new ArrayList();

    for (int i = 0; i < count; i++) {
      MailItem item = (MailItem) items.get(i);
      if (i < (count / 2)) {
        inlist.add(item);
      } else {
        sentlist.add(item);
      }
    }

    inbox.set("children", inlist);
    sent.set("children", sentlist);
    trash.set("children", new ArrayList());

    add(inbox);
    add(sent);
    add(trash);

  }			

  ...

}

If you take a look at the MailModel.java class, you’ll notice that its primary purpose is to model the mail part of the application (with Tasks and Contacts being the other parts). It has an inbox, sent, and trash folders. In this simplistic application, also notice that the mail items are being populated right here in the model, line 12, and that the inbox/sent folders are being populated with a simple for-loop line 18-25). This will most likely NOT be the case for your applications, as you’ll probably want to populate the models with some server-side data.

/com/extjs/gxt/samples/mail/client/mvc

/AppController.java
/AppView.java
/ContactController.java
/ContactFolderView.java
/ContactView.java
/MailController.java
/MailFolderView.java
/MailView.java
/TaskController.java
/TaskFolderView.java
/TaskView.java

You’ll find all of our MVC controllers and views in this folder. The AppController is the main controller responsible for setting up our entire app. I will go into more detail on this and the other controllers in the MVC section (below).

/com/extjs/gxt/samples/mail/client/widget

/ContactPanel.java
/LoginDialog.java
/MailItemPanel.java
/MailListPanel.java
/TaskPanel.java

This folder contains all of the application-specific widgets. As GXT is a framework, expect to extend and customize application-specific widgets as your application requires. For this app, the widgets that are used to organize the mail list (MailListPanel.java), display the contents of a mail item (MailItemPanel.java), display contacts, and display tasks are defined here. The LoginDialog widget is the widget you first see when logging in to the application.

Each of these widgets will be instantiated by the views responsible for displaying their respective data.

For the most part, these widgets are fairly simple. I will say a few things about the LoginDialog widget. The LoginDialog widget extends from the GXT class Dialog and expects a username/password (you can enter anything with at least 4 characters) and will allow you to login only after it has been validated (has at least 4 chars and the username has a value). You can see that this behavior is enabled from the source code of the LoginDialog.java widget:

public class LoginDialog extends Dialog {

...
	public LoginDialog() {
	  ...
	    KeyListener keyListener = new KeyListener() {
	      public void componentKeyUp(ComponentEvent event) {
	        validate();
	      }

	    };
	  ...
	}

  protected void validate() {
    login.setEnabled(hasValue(userName) && hasValue(password) && password.getValue().length() > 3);
  }
...

}

Once you click the “Login” button, the “onSubmit” method will be called which runs a timer (to simulate a user logging in… again.. this is trivial because it’s a sample app. In your app, you can do your login logic here) and then hides the LoginDialog widget:

  @Override
  protected void createButtons() {

  	...
  	login = new Button("Login");
  	login.disable();
  	login.addSelectionListener(new SelectionListener() {
      public void componentSelected(ButtonEvent ce) {
        onSubmit();
      }
    });

    ...
   }

   ...

  protected void onSubmit() {
    buttonBar.getStatusBar().showBusy("Please wait...");
    buttonBar.disable();
    Timer t = new Timer() {

      @Override
      public void run() {
        LoginDialog.this.hide();
      }

    };
    t.schedule(2000);
  } 

If you’re wondering how the LoginDialog widget gets displayed, it’s part of the MVC execution. See below.

Understanding the GXT Model-View-Controller

The main structure of the mail application is controlled by the GXT MVC implementation. The overview functionality is as follows: the dispatcher fires an application event (one of the events enumerated in /client/AppEvents.java) to all of the controllers. If the controller can handle that particular event, it does. If it can’t handle the event it doesn’t do anything. The controller is responsible for executing logic and updating any models. The views that are connected to these
controllers will update accordingly after a model is updated.

For all of this to happen, the dispatcher must register the controllers to which it can fire events. Going back to our /client/Mail.java entry-point class, the dispatcher is initialized and
the controllers are passed to it:

public class Mail implements EntryPoint {

  public void onModuleLoad() {
    ...
    Dispatcher dispatcher = Dispatcher.get();
    dispatcher.addController(new AppController());
    dispatcher.addController(new MailController());
    dispatcher.addController(new TaskController());
    dispatcher.addController(new ContactController());
    ...
  }
}

At this point, we have the four controllers registered with the dispatcher. Now that the dispatcher has controllers, it can fire events to these controllers:

public class Mail implements EntryPoint {

  public void onModuleLoad() {
    ...

	dispatcher.dispatch(AppEvents.Login);

    ...
  }
}

Again notice, the event we fire is derived from our AppEvents.java file; in this case we’re firing the ‘Login’ event.

Only controllers that can handle the ‘Login’ event will service this event. Which controllers are that? The ones that explicitly register for this event. In the case of the mail application, the AppController is the only controller that can handle ‘Login’ events. We can tell this by looking at the constructor for the AppController:

public class AppController extends Controller {

  private AppView appView;
  private MailServiceAsync service;

  public AppController() {
    registerEventTypes(AppEvents.Init);
    registerEventTypes(AppEvents.Login);
    registerEventTypes(AppEvents.Error);
  }

  ...
}

You might want to be aware of what’s going on in the background: before the dispatcher queries a controller to determine whether it can handle a particular event, the dispatcher determines whether or not the controller is initialized. If it’s not initialized, the initialize() method will be called on the controller. Inside this method is where you want to put all logic associated with setting up the controller. See the example in the AppController.initialize() method:


  public void initialize() {
    appView = new AppView(this);
  }

Although this initialization is trivial, it is called once when the controller is initialized, and is the suggested place to put all initialization code. Hopefully that explains the mysterious initialize() method in the Controller classes.

In this example, since the AppController can handle Login events, the event is passed to the controller’s handleEvent(AppEvent event) method. This is a method that must be implemented when extending the GXT Controller class. Inside the handleEvent method, you can determine what type of event occurred and deal with it accordingly:

public class AppController extends Controller {
  ...
  public void handleEvent(AppEvent event) {
    switch (event.type) {
      case AppEvents.Init:
        onInit(event);
        break;
      case AppEvents.Login:
        onLogin(event);
        break;
      case AppEvents.Error:
        onError(event);
        break;
    }
  }
  ...

  protected void onError(AppEvent ae) {
    System.out.println("error: " + ae.data);
  }

  private void onInit(AppEvent event) {
    forwardToView(appView, event);
    service = (MailServiceAsync) Registry.get("service");
    service.getMailFolders("darrell", new AsyncCallback() {
      public void onFailure(Throwable caught) {
        Dispatcher.forwardEvent(AppEvents.Error, caught);
      }

      public void onSuccess(Folder result) {
        Dispatcher.forwardEvent(AppEvents.NavMail, result);
      }
    });

  }

  private void onLogin(AppEvent event) {
    forwardToView(appView, event);
  }  

}

When the Login event is handled by the controller, it is processed and then forwarded to the appropriate view. This again is trivial for the sample app. In a more complicated app, processing of the models would occur here, and forwarding to the view would only be necessary for some specific view-only logic. In this case, the event is forwarded to the view, however, you might notice something from looking at the source: views also implement a handleEvent method, but the AppView class doesn’t seem to be able to handle Login events:


public class AppView extends View {
  public AppView(Controller controller) {
    super(controller);
  }
  ...

  protected void handleEvent(AppEvent event) {
    switch (event.type) {
      case AppEvents.Init:
        initUI();
        break;

    }
  }
}

What happened? Very similarly that the controllers have their initialize method called before they are available to handle any events, the Views are also initialized before they handle any events. This happens only once if the view is not initialized. Thus, in this case, the initialize() method on the AppView class was called before the Login event was forwarded. You can see in the initialize() method, the view sets up the LoginDialog panel before adding anything else to the screen. Firing the Login event really had the effect of only initializing the view. The view did not directly handle the event (although it could have):


public class AppView extends View {
  ...
  protected void initialize() {
    LoginDialog dialog = new LoginDialog();
    dialog.setClosable(false);
    dialog.addListener(Events.Hide, new Listener() {
      public void handleEvent(WindowEvent be) {
        Dispatcher.forwardEvent(AppEvents.Init);
      }
    });
    dialog.show();
  }
  ...
}

Notice that a framework listener for the Events.Hide framework event is added to the LoginDialog widget. That means when the dialog.hide() method is called (as it will be in the onSubmit method from the LoginDialog.java class), the Events.Hide event will fire and this listener will be called. Inside the listener you can see that once the login has taken place, a new event, Init will be fired by the dispatcher to its controllers. The process for querying the controllers and forwarding the event to the appropriate controller happens again. Notice the event is being fired with the Dispatcher.forwardEvent(AppEvent e) call instead of the Dispatcher.dispatch() method. They both accomplish the same task, but I believe the Dispatcher.forwardEvent is the recommended way to make calls to the dispatcher from within controllers or views.

When the Init event is fired, the controllers are again queried to determine which controllers can handle this event. In the mail app, all of the controllers can handle the Init event. In the AppController, the onInit() method gets called for an Init event, and this does two things: forwards the event to a view (which does all of the logic for instantiating the actual widgets) and calls a GWT-RPC service method to get the mail folders from the server. When the response is sent back from the server, a new event is fired: NavMail.


public class AppController extends Controller {
  ...
  private void onInit(AppEvent event) {
    forwardToView(appView, event);
    service = (MailServiceAsync) Registry.get("service");
    service.getMailFolders("darrell", new AsyncCallback() {
      public void onFailure(Throwable caught) {
        Dispatcher.forwardEvent(AppEvents.Error, caught);
      }

      public void onSuccess(Folder result) {
        Dispatcher.forwardEvent(AppEvents.NavMail, result);
      }
    });

  }
  ...
}

The NavMail event is fired along with a folder obeject. The controller/view that handles this event can use this folder as the default folder to expand

The AppView instantiating the widgets:


public class AppView extends View {
  ...
  protected void handleEvent(AppEvent event) {
    switch (event.type) {
      case AppEvents.Init:
        initUI();
        break;

    }
  }
  ...
  private void initUI() {
    viewport = new Viewport();
    viewport.setLayout(new BorderLayout());

    createNorth();
    createWest();
    createCenter();

    // registry serves as a global context
    Registry.register("viewport", viewport);
    Registry.register("west", west);
    Registry.register("center", center);

    RootPanel.get().add(viewport);
  }  

}

Additionally, note that the AppController is just one of the controllers that handles the Init event. The other controllers also handle the event, and set up their views and models accordingly.

When the NavMail event is fired, the only controller that can handle that event, the MailController, forwards it on to its two views: MailView and MailFolderView. MailView sets up the widgets to display the list of mail (MailListPanel) and the mail-item content (MailItemPanel); MailFolderView loads the mail items associated with the folder that was passed along with the event when the NavMail event is handled.


public class MailFolderView extends View {
  ...
  protected void handleEvent(AppEvent event) {
    switch (event.type) {
      case AppEvents.Init:
        initUI();
        break;
    }

    if (event.type == AppEvents.NavMail) {
      Folder f = (Folder) event.data;
      if (f != null) {
        loader.addListener(Loader.Load, new LoadListener() {
          @Override
          public void loaderLoad(LoadEvent le) {
            loader.removeLoadListener(this);
          }
        });
        loader.load(f);
      }

    }
  }
  ...
}

Note that the reason you see the mail widgets and mail items when you login is because all of these events (Login, Init, NavMail, executed and the controllers and views worked as designed: the controllers handled the events, the views updated their widgets (or the widgets updated themselves).

If I have left something out, or you feel something should have been explained in more detail, please leave me a comment!