Thursday, August 03, 2006

Introduction to Echo2 with Maven, Eclipse, and Jetty

I've been dragging my feet about entering the AJAX fray. Thetechnology landscape surrounding AJAX feels very fragmented to me. Where does one begin? Which toolkits will merge to form the standard? Which will be dropped? Not to mention the fact that I'm not an expertWeb developer and would rather leave HTML, CSS, and JavaScript todesigners than be mucking with it myself. As a result, I've chosenmore conventional programmatic GUI toolkits like Swing or Eclipse's SWTfor writing rich client applications. The truth is though, that peopleoften cringe when they hear the word "Applet", and installing a "fat"client on users' desktops is not always an option. And so the searchfor the holy grail begins, a UI technology that does a reasonable jobof meeting these criteria:
  1. Natural Programming Model-- The developer should be able to interact with the UI controls thatmake up the toolkit in a natural OO way. Preferrably, in a language wealready know.
  2. Modern Tool Support-- Developers should be able to easily debug and unit test code writtenwith the toolkit and make use of modern IDE features like refactoring
  3. Ubiquitous Deployment-- Applications written with the toolkit should be easily deployable toa large audience. This means no non-standard plugin installations,browser compatibility hassles, and no "large" downloads
  4. Rich Client Features-- Developers should be able to easily implement Rich Client Featureslike controls that update in real-time, drag-n-drop, resizing panes,popups, dialogs, etc.

The rest of this post will focus on a toolkit that meets the above criteria, Echo2,an open source AJAX-based framework. Developers write their UI code inJava, interacting with the UI controls much like they would if theywere writing a Swing application, but the control itself is splitbetween the web browser and server. For a given user, the state of theUI controls is maintained in the user's session, while the "view"portion of the controls is rendered in the user's web browser.

Hello World Application

I'llstart with a really simple application, simply putting a button on thescreen. The purpose of this example application will be simply to geta development environment setup and a simple application working.

To complete this tutorial, you'll need the following tools:
  • Eclipse IDE -- Available for download here
  • Maven 2 -- Available for download here
  • Echo2 -- Available for download here
We'll use Eclipse to write some Java code and Maven 2 to ease some of the build and deployment stuff.

Creating the Web Project

We'lluse maven to create the boilerplate web app project. Echo2 apps can bedeployed as a war file in any java servlet container. If we usemaven's archetype plugin to create our web app project, then we canalso use maven to do the rest of our build tasks without any additionalconfiguration including compiling our source code, creating and anddeploying our war file, etc.

In a temp directory, create a new project using the following maven 2 command
mvn archetype:create -DgroupId=org.softsoup.echo2 -DartifactId=echo2-hello -DarchetypeArtifactId=maven-archetype-webapp

Thiscommand creates a new directory, "echo2-hello" that contains your newweb app project with some standard directories and files precreated sothat the other maven plugins will know where to look for things when weask it to build the war file, etc. This command also creates thepom.xml document for this project and puts it in the root folder of theproject ("echo2-hello"). This pom.xml document is read by maven tofind out things about your project like your project's dependencies andwhat type of artifact (jar, war, etc) to build from your project.

Adding Echo2 Dependencies

We're going to be writing some classes that will use the Echo2 jars, so we need to add them to our project as dependencies.

Installing the Echo2 jars into Local Maven Repository

Assuming you've downloaded and unzipped the Echo2 distribution in <echo2-home>, run the following commands to copy the Echo2 jars into your local Maven repository:

mvn install:install-file
-Dfile=<echo2-home>/BinaryLibraries/Echo2_App.jar
-DgroupId=echo2 -DartifactId=Echo2_App -Dversion=2.0 -Dpackaging=jar
mvn install:install-file
-Dfile=<echo2-home>/BinaryLibraries/Echo2_WebContainer.jar -DgroupId=echo2 -DartifactId=Echo2_WebContainer -Dversion=2.0 -Dpackaging=jar
mvn install:install-file
-Dfile=<echo2-home>/BinaryLibraries/Echo2_WebRender.jar
-DgroupId=echo2 -DartifactId=Echo2_WebRender -Dversion=2.0 -Dpackaging=jar
There should now be a folder "echo2" under <your-home-dir>/.m2/repository. This folder will contain a folder for version 2.0 which should contain the jars.

Declaring the Dependencies In pom.xml

Now,add the following tags to the dependencies section of the pom.xmldocument located at the root of your echo2-hello project:
<dependency>
<groupId>echo2</groupId>
<artifactId>Echo2_App</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>echo2</groupId>
<artifactId>Echo2_WebContainer</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>echo2</groupId>
<artifactId>Echo2_WebRender</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
</dependency>

Thistells maven to look for these jars when doing builds, packaging etc. NOTE: while our code will not directly depend on the servlet-api, theEcho2 libraries do, so we include the servlet-api as a dependency.

Before moving on to the next step, cd to the echo2-hello directory and run:

mvn compile

Wedon't have any source yet, so it won't really compile anything, butthis will force maven to download all of our declared dependencies thathaven't already been installed into our local repository. In thiscase, we manually installed the echo2 libraries, so it should onlydownload the java servlet api jar.

Importing Into Eclipse

If you're using Eclipse, you'll want tocreate an Eclipse project for our new project and then import it intoEclipse. Maven provides a plugin for creating the Eclipse projectfiles from a maven project. from your new echo2-hello directory, runthe following command:

mvn eclipse:eclipse

Notice thatthis command created the .project and .classpath files in yourecho2-hello directory. Now you can import the project into the Eclipseworkspace. Launch Eclipse and choose File->Import->ExternalProjects into Workspace. Select the echo2-hello project. It shouldnow appear as a project in Eclipse's package explorer.

Now, to the Coding!

Adda folder for our project's Java source tree at...echo2-hello/src/main/java. Create a package within that sourcetree, org.softsoup.echo2.hello.

To get our web app up andrunning, Echo2 requires that we create only the following two classeswhich we'll put in our new package.

The application UI class itself, an instance of one of these will be created for each user:
public class HelloWorldApp extends ApplicationInstance {

public Window init() {

// create the root window, content pane,
// window pane, and a button
Window window = new Window();
ContentPane contentPane = new ContentPane();
final WindowPane windowPane = new WindowPane("hello world", null, null);
Button button = new Button("click me");

// add an action listener to the button that changes
// the window pane's title when clicked
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
windowPane.setTitle("hello world " + new Date());
}
});

//add the controls to the screen
windowPane.add(button);
contentPane.add(windowPane);
window.setContent(contentPane);
window.setTitle("hello, world!");

return window;
}
}


OurHelloWorldApp will have a window pane on the screen and a button whichwhen clicked will update the title of the window pane. Notice howhandling the button click is as simple as registering an ActionListenerwith the button. NOTE: the ActionListener here is an interfacedefined as part of the Echo2 API's, not thejava.awt.event..ActionListener.

and a servlet to create the app instances, one instance of these will be created per deployment:
public class HelloWorldServlet extends WebContainerServlet { public ApplicationInstance newApplicationInstance() { return new HelloWorldApp(); } }

Configuring the web.xml

Sinceour Echo2 apps is deployed as a servlet, we need to register ourHelloWorldServlet with the servlet container by editing the boilerplateweb.xml file that maven created atecho2-hello/src/main/webapp/WEB-INF/web.xml. Edit it to look likethis:
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<display-name>Hello SoftSoup!</display-name>
<description>
"Hello, SoftSoup!" Application
</description>

<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>org.softsoup.echo2.hello.HelloWorldServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>

</web-app>


This tells the web container that any url's matching "/app" will be dispatched to our HelloWorld echo2 application.

Configuring the Jetty Plugin for Maven

TheJetty plugin for maven will help us to quickly test our app. Basically, the jetty plugin will take a standard Maven web app project(which we have!), and run it within the jetty servlet container withoutassembling the project into a war file. Also, we can configure it toperiodically scan our project for changes, redeploying any changes itfinds automatically. This means that we could sit down in the morningto work on our echo2 app, launch the jetty plugin using, Then let itrun all day while we make changes to our project and test them using aweb browser.

First though, we need to declare our use of this special plugin in our pom.xml file as follows:

...
</dependencies>
<build>
<finalName>echo2-hello</finalName>
<plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> </configuration> </plugin> </plugins>
</build>
</project>


Running the App

Now, run the Jetty plugin using:

mvn jetty:run

This launches our app in the Jetty servlet container on port 8080.

Load the Hello World app using http://localhost:8080/echo2-hello/app

What's Next

I'lltry to make a follow up post that demonstrates some of the moresophisticated features of Echo2 including their "push" stuff which is abig part of the "richness" of RIA's.