Developer: SOA
   DOWNLOAD
 Oracle JDeveloper 10g
 OC4J 10g standalone
 Sample code
   TAGS
soa, java, opensourceAll

Introduction to the Google Web Toolkit


by  Stéphanie Antoine, Julien Dubois, and Jean-Philippe Retaillé

Learn how to use the Google Web Toolkit to do everything from basic tasks to advanced ones such as RPC communication, history management, and packaging a production-ready application. 

Published October 2006

Web 2.0 and its technical counterpart, Asynchronous JavaScript and XML (Ajax), are gaining momentum thanks to applications such as Gmail and Google Maps. For Web applications, the main benefit of Ajax is a greatly improved user experience. Although JavaScript and DHTML—the technical foundations of Ajax—have been available for years, most programmers ignored them because they were difficult to master. Today, frameworks written in JavaScript, such as Dojo, can help you build Ajax applications, but you still need a good understanding of JavaScript in order to use them. Google offers another way to help Java developers create Ajax applications more productively. This new framework, called Google Web Toolkit (GWT), can be used efficiently with Oracle JDeveloper. GWT is freely available under the Apache License v. 2.0 at http://code.google.com/webtoolkit.

Main Features and Restrictions


One of the main problems with Ajax development is that you need to master a large stack of heterogeneous technologies. Depending on the nature of your project (for example, business applications), this can be a great drawback.

In addition, different Web browsers don’t support JavaScript and DHTML in the same way. For example, Microsoft Internet Explorer and Mozilla Firefox handle these technologies slightly differently; you’ll need to deal with this if you want your application to run seamlessly on your users’ PCs.

Although most of the Ajax frameworks available today simplify development work, you still need a good grasp of the technology stack. So, if you’re planning to use Ajax to improve only your application’s user experience—if you’re not also using it as a strategic advantage for your business—it may be unwise to spend a lot of money and time on the technology.

GWT proposes a different way to create Ajax applications. It uses Java as a single programming language for both the client and server sides. Is it the return of Java applets? Not at all: GWT provides a compiler that translates the Java code on the client side into JavaScript and DTHML. This solution greatly simplifies the technology stack from the programmer’s point of view: You have to master only Java. The downside is that you have less control over the client-side code of your application because it’s eventually generated by the GWT compiler.

The Java code for the client side of your application is subject to restrictions because JavaScript doesn’t implement the entire object-oriented concepts and APIs available in Java. You can use only a subset of Java keywords and APIs (java.lang and java.util):
  • All the primitive types (such as byte, char, short, and int) as well as their corresponding classes (such as Byte and Char) are directly supported—except for long, which is translated into the JavaScript equivalent of double. We recommend that you use int instead of long.
  • User-defined exceptions (checked or not) are possible but the method Throwable.getStackTrace() is not available. Some JVM exceptions are also available (such as IndexOutOfBoundException).
  • The keyword synchronized has no effect because JavaScript is mono-thread. The multithread API is not available.
  • Reflection is not supported. However, you can get the class name of an object by using the method GWT.getTypeName(Object).
  • Finalization is not supported.
  • Several objects containers from java.util can be used, such as Stack, Vector, and HashMap. The Date class is also available.
In addition, GWT provides specific APIs to manage the GUI, internationalization, and XML parsing. It also provides a comprehensive library to manage communication between the client and the server. It uses well-known Remote Procedure Call (RPC) principles implemented by a generic servlet (RemoteServiceServlet), which you can specialize for your own needs. You also can use JavaScript Object Notation (JSON) as the data interchange format for your HTTP messages sent with the GWT HTTPRequest class.

GWT also offers an interface, called JavaScript Native Interface (JSNI), which lets you mix your own hand-made JavaScript code with the code generated by the GWT compiler. JSNI uses the keyword native used by Java Native Interface (JNI) to define your own JavaScript functions. The body of these functions is defined inside specifically formatted comments.

Finally, you can unit-test your code inside JDeveloper with GWTTestCase, a specialization of the class TestCase provided by JUnit.

Focus on GUI Programming with GWT


Ajax dramatically changes the way you develop Web applications. Most of the time, an Ajax application needs only a single Web page. Its content is modified dynamically by JavaScript and DHTML to produce a user experience similar to that provided by native applications.

Therefore, GWT provides a programming model whose principles will sound familiar to Swing or AWT programmers. The GUI is no longer specified by HTML tags as in classic Web applications. It’s programmed directly with Java code in a way similar to AWT or Swing. The well-known concepts of GUI programming are available with GWT:

  • Widgets, including the usual items (such as Button, TextBox, and CheckBox) and more advanced items such as Tree and Menu Bar
  • Panels, which contain widgets, with their own layout (panels and layout aren’t separated as in Swing)
  • Events generated by widgets. The listeners must implement specific interfaces.
Loading the GWT JavaScript library and specifying the entry point of your application is easy: all you have to do is create a simple HTML page.

GWT uses Cascading Style Sheets (CSS). Every widget has its own style, which you can change to meet your needs. You must create your own CSS to overload the defaults defined by GWT.

If the standard widgets don’t suit your needs, you can also define your own. (This topic, however, is beyond the scope of this article.)

Project Structure

A GWT project must comply with a pre-defined structure in order to be accepted by the compiler. Thus, it’s mandatory that you define a global package for your application. The last part of the package name must be the name of the application (such as global.package.yourApplicationName). The XML file describing your application must be found at the root of this global package. The name of this file must be the name of the application followed by the .gwt.xml extension (for example, yourApplicationName.gwt.xml). In addition, you must create three sub-packages:

  • “client”, which contains the Java code of the client side (this code must comply with the restrictions mentioned earlier)
  • “server”, which contains the Java code of the server side (you can use the full J2SE/J2EE API here)
  • “public”, which contains the HTML pages, CSS, and images of your application
Your project must declare several jars:
  • gwt-dev-windows.jar or gwt-dev-linux.jar: Programming tools including the compiler. The embedded Web browser provided by GWT is platform-dependent.
  • gwt-user.jar: The GWT runtime.
  • gwt-servlet.jar: The jar to deploy on your application server with the code generated by the GWT compiler. It contains the RemoteServiceServlet.
The result of the compilation is stored in a single directory whose name is the name of the global package of your application. This directory contains all the elements (such as HTML pages, CSS, and JavaScript files) that comprise the client side of your application. These elements must be deployed inside your Web application, as usual.

Hosted and Web Modes


Two execution modes are possible with GWT. The Hosted mode executes your application code inside an embedded server and Web browser, so you don’t have to deploy your code on an application server. It’s useful during application testing because it makes debugging simpler.

The Web mode is the deployment of your Ajax Web application on a genuine application server such as OC4J. You typically use this mode when the application runs in production.

Building Your First GWT Web App with Oracle JDeveloper

Thus far you've learned how GWT works; now, let’s code a sample Web application ( download).

The sample application is a to-do list manager. Its features are quite simple: creating, editing, deleting, and prioritizing to-do lists. We chose this example because it’s easy to understand, yet its implementation covers a lot of GWT’s features.

Here’s a screen shot of the final application:

figure 1

Step 1: Install GWT

Download GWT from Google’s Web site at http://code.google.com/webtoolkit/. At the time of this writing, GWT comes in Windows and Linux versions. GWT is platform-specific because its Hosted mode works with a modified version of Firefox, which is itself platform-dependent. (We were able to use the Linux version of GWT successfully on an Apple computer, but the Hosted mode didn’t work.)

GWT downloads as an archive file, which you must uncompress either with the tar -xvf command on Linux or with an unzip utility on Windows. That’s all you need to do to install the toolkit.

Step 2: Run the applicationCreator Script

Open a command line and go to GWT’s installation directory. This directory contains the applicationCreator script, which we’ll use to start up our application. Because we want our application to be stored in the Oracle Technology Network directory, we add “-out otn” as a parameter to the script. On Linux, type:

./applicationCreator -out otn otn.todo.client.TodoApp
                              

figure 2

On Windows, use:

applicationCreator -out otn otn.todo.client.TodoApp
                              
This script generates the basic project structure, a sample “Hello word” code inside the requested application class, as well as two scripts: TodoApp-shell, which is used to run the application in Hosted mode; and TodoApp-compile, which is used to package the application for use in Web mode.

Step 3: Open the Project in JDeveloper

Launch JDeveloper and create a new Web project:

figure 3

Click on the Next button. JDeveloper will ask for the new project’s location. Use your application’s name as the Project Name, and choose the application root directory, as defined in Step 2, as the Directory Name:

figure 4

Click on the Next button and validate that your application is a J2EE 1.4 application:

figure 5

Click on the Next button and choose your project Web properties: the Document Root is the current project’s www directory, and the J2EE Web Application Name and J2EE Context Root are both the project name:

figure 6

This will create the JDeveloper project, but some compilation errors will occur because GWT’s library isn’t included in the project classpath. In the project properties, select the Libraries node in the side tree on the left and add the gwt-user.jar library:

figure 7

Your project should now compile and look like this:

figure 8

Writing the Client-side Code

The applicationCreator script above created a basic “Hello world” application, which is available in the otn.todo.client package. Here's its main method:

public void onModuleLoad() {
                              
final Button button = new Button("Click me");
final Label label = new Label();

button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
if (label.getText().equals(""))
label.setText("Hello World!");
else
label.setText("");
}
});

RootPanel.get("slot1").add(button);
RootPanel.get("slot2").add(label);
}
}
This method creates a button that says “Click Me”. When you click the button, the text “Hello World” is displayed.

This method is divided into three parts:

  1. The creation of the Button and Label widgets
  2. The creation of a ClickListener object. This code is very close to what you would have written in Swing; it’s easier to understand if you have a desktop Java background.
  3. The display of the widgets on the HTML page: slot1 and slot2 are both HTML elements on the page
The HTML page that’s used as a skeleton is located in the src/otn/todo/public directory. It defines the two HTML elements, slot1 and slot2, as table cells.

Running and Debugging in Hosted Mode


Now that you’ve created the application and have seen what it generates, let’s execute it.

You can easily run the project by using the TodoApp-shell script from the command line. Although this is a perfectly correct way to launch the application, you might prefer to launch it directly from within JDeveloper. To do so, click the Run menu and select Choose Active Run Configuration > Manage Run Configurations. Edit the default run configuration and use the following:

  • For the Default Run Target: Use the com.google.gwt.dev.GWTShell that’s inside your platform-specific GWT jar. On Linux it will look like this:
    path.to.your.gwt.installation.directory/gwt-devlinux.jar!/com/google/gwt/dev/GWTShell.class
                                      
    On Windows it will look like this:
    path.to.your.gwt.installation.directory/gwt-dev-windows.jar!/com/google/gwt/dev/GWTShell.class
                                      
  • For the Program Arguments, use:
    -out path.to.your.gwt.installation.directory/otn/www otn.todo.TodoApp/TodoApp.html
                                      
  • For the Run Directory, use
    path.to.your.gwt.installation.directory/otn
                                      
The end result should look like this:

figure 9

To run your application, you must add two more libraries to its classpath: the GWT platform-specific jar and the application’s src directory:

figure 10

You should now be able to run the application from JDeveloper.

This was quite a complicated setup, but thankfully, you can reuse it for debugging the application: just use the Debug button instead of the Run button. You can then use the debugger as usual—set breakpoints, execute the code step-by-step, and so on:

figure 11

What’s particularly impressive about this feature is that you can debug the client-side code written in Java with the standard JDeveloper debugger.

Extending Your GWT Web App

Now that you’ve created a simple GWT Web application, let’s extend it using two of the most commonly used GWT features: the RPC mechanism, which allows the application to call server-side code, and the History object, which allows the user's precise handling of the browser’s Back button.

Data Exchange Between Client and Server Using RPC

Thus far, you’ve created only the client-side code of our application: using the GWT compiler, you’ve generated a number of HTML and JavaScript files that will run in the end-user’s browser. However, this application won’t be of much use if it can’t communicate with the server.

With GWT, client/server communication is a matter of coding a servlet and making it communicate with the application. Here’s what you have to do.

Create an interface that defines your service. This interface must extend Google’s com.google.gwt.user.client.rpc.RemoteService interface, and be placed into the client package (otn.todo.client, in our example).

Next, code an interface that lets you read and write a to-do list on the server:

package otn.todo.client;
                              
import java.util.List;
import com.google.gwt.user.client.rpc.RemoteService;
public interface TodoListBackupService extends RemoteService {
/**
* Save the to-do list on the server.
*/
void saveTodoList(List todoList);
/**
* Get the to-do list on the server.
*/
List getTodoList();
}
Code the Servlet. On the server side, you must code a class that:
  1. Extends Google’s com.google.gwt.user.server.rpc.RemoteServiceServlet class (which, in turn, extends Java’s javax.servlet.http.HttpServlet, effectively making it a servlet)
  2. Implements the interface written in Step 1
  3. Is located in the server package (otn.todo.server, in our example)
package otn.todo.server;
                              

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import otn.todo.client.Todo;
import otn.todo.client.TodoListBackupService;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class TodoListBackupServiceImpl extends RemoteServiceServlet implements
TodoListBackupService {

private static final String TODOLIST_KEY = "TODOLIST_KEY";

public void saveTodoList(List todoList) {
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession();
session.setAttribute(TODOLIST_KEY, todoList);
}

public List getTodoList() {
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession();
if (session.getAttribute(TODOLIST_KEY) == null) {
List todoList = new ArrayList();
Todo todo = new Todo("Hello from the server");
todoList.add(todo);
return todoList;
} else {
return (List) session.getAttribute(TODOLIST_KEY);
}
}
}
This servlet stores only the to-do list in the user’s HttpSession; this, of course, is a basic way of saving data. In a normal application, you could use JNDI to access EJBs, or any of the classic patterns used to access a business service from a servlet.

Finally, you must configure this servlet inside the servlet container. If you’re using the GWT shell, you can configure it inside the *.gwt.xml configuration file, which is TodoApp.gwt.xml in our example:

<module>
                              
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Specify the app entry point class. -->
<entry-point class='otn.todo.client.TodoApp'/>
<servlet path="/todoListBackupService" class="otn.todo.server.TodoListBackupServiceImpl"/>
</module>
If you want to configure it within another application server, such as OC4J, just add the usual XML configuration into the WEB-INF/web.xml file:
<servlet>
                              
<servlet-name>TodoListBackupService</servlet-name>
<servlet-class>otn.todo.server.TodoListBackupServiceImpl</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>TodoListBackupService</servlet-name>
<url-pattern>/todoListBackupService</url-pattern>
</servlet-mapping>
Add some glue. The glue we need is the Async class, which must follow several rules:
  • It’s located in the client package (otn.todo.client).
  • It has the same name as the interface described in Step 1, with the addition of Async at the end.
  • It has the same methods as the interface described in Step 1, but they all get an additional parameter, com.google.gwt.user.client.rpc.AsyncCallback callback.
package otn.todo.client;
                              

import java.util.List;
                                 

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface TodoListBackupServiceAsync {

/**
* Save the to-do list on the server.
*/
void saveTodoList(List todoList, AsyncCallback callback);

/**
* Get the to-do list on the server.
*/
void getTodoList(AsyncCallback callback);
}
    Use it inside the application. To access the server-side code from within the client application, use the com.google.gwt.core.client.GWT class, which can create a very special object:
    TodoListBackupServiceAsync todoListBackupService = (TodoListBackupServiceAsync) GWT.create(TodoListBackupService.class);
                                  
    This creates at runtime a class implementing two interfaces:
    • The Async interface we just coded in Step 3
    • Google’s com.google.gwt.user.client.rpc.ServiceDefTarget interface
    The second interface is used to configure the class so that it can point to the servlet defined in Step 2:
    ServiceDefTarget endpoint = (ServiceDefTarget) todoListBackupService; endpoint.setServiceEntryPoint("/todoListBackupService");
                                  
    Now that you’ve configured this object to access the server-side service, let’s access the service. As you’ve seen in Step 3, the Async interface lets you access all the methods defined in the service, with the addition of the AsyncCallback callback parameter. This parameter is used to define the application’s behavior, depending on the success or failure of the server-side call:
     AsyncCallback callback = new AsyncCallback() {
                                  
    public void onSuccess(Object result) {
    printTodoList();
    }

    public void onFailure(Throwable caught) {
    Window.alert("Warning : the to-do list could not be saved on the server. Maybe the server is down.");
    }
    };
    Let’s put it all together. Here’s the complete code of the two client-side methods accessing the TodoListBackupService business service: one for saving the to-do list on the server side, the other for reading it:
     /**
                                  
    * Update the to-do list with data from the server.
    */
    private void updateTodoListFromServer() {
    TodoListBackupServiceAsync todoListBackupService =
    (TodoListBackupServiceAsync)GWT.create(TodoListBackupService.class);

    ServiceDefTarget endpoint = (ServiceDefTarget)todoListBackupService;
    endpoint.setServiceEntryPoint("/todoListBackupService");

    AsyncCallback callback = new AsyncCallback() {
    public void onSuccess(Object result) {
    todoList = (List)result;
    saveTodoListInHistory();
    }

    public void onFailure(Throwable caught) {
    Todo todo =
    new Todo("ERROR!! Server could not be reached.");
    todoList.add(todo);
    saveTodoListInHistory();
    }
    };

    todoListBackupService.getTodoList(callback);
    }

    /**
    * Save the to-do list on the server.
    */
    private void saveTodoListOnServer() {
    saveTodoListInHistory();

    TodoListBackupServiceAsync todoListBackupService =
    (TodoListBackupServiceAsync)GWT.create(TodoListBackupService.class);

    ServiceDefTarget endpoint = (ServiceDefTarget)todoListBackupService;
    endpoint.setServiceEntryPoint("/todoListBackupService");

    AsyncCallback callback = new AsyncCallback() {
    public void onSuccess(Object result) {
    printTodoList();
    }

    public void onFailure(Throwable caught) {
    Window.alert("Warning : the to-do list could not be saved on the server. Maybe the server is down.");
    }
    };

    todoListBackupService.saveTodoList(todoList, callback);
    }
    The example application makes a server-side call at startup. This call returns the latest to-do list saved in the user’s HttpSession, or a new to-do list containing the “Hello from the server” to-do:

    figure 12

    Managing the Back Button

    In high-end Web applications, the browser’s Back button is too often broken. Classic Ajax applications don’t support the standard Web behavior of returning you to the previous Web page.

    GWT, on the other hand, allows for programmatic handling of the Back button. This is a powerful yet tricky feature that we’ll explore using our example application. The idea is to use the Back button as an Undo button: clicking it will show you the to-do list as it was before the latest event. Similarly, the Forward button will work as a Redo button.

    Implement the HistoryListener interface. In order to manage the Back button programmatically, the GWT application must implement the com.google.gwt.user.client.HistoryListener interface. This forces the writing of the onHistoryChanged(String _historyToken) method:

    public class TodoApp implements EntryPoint, HistoryListener {
                                  

    /**
    * This method is called whenever the application's history changes.
    */
    public void onHistoryChanged(String _historyToken) {
    if (Integer.parseInt(_historyToken) + 1 != historyToken) {
    if (historyMap.get(_historyToken) != null) {
    historyToken = Integer.parseInt(_historyToken);
    todoList = (List) historyMap.get(_historyToken);
    }
    }
    printTodoList();
    }
    This method is meant to receive events when the browser’s history is changed. You must add it as a listener to the GWT’s History object. This is typically done in the onModuleLoad() method, so that the History object is correctly initialized at startup:
     /**
                                  
    * This is the entry point method.
    */
    public void onModuleLoad() {

    History.addHistoryListener(this);

    }
    Now, the onHistoryChanged(String _historyToken) method is called each time the browser’s history is changed.

    This method is able to recreate the application’s state according to a token that’s passed as a parameter. In our example, you'll use that token as a key to find a to-do list stored inside a history map.

    Add items to the history. In order for the onHistoryChanged(String _historyToken) method to work, you must have stored items in the history beforehand.

    This is easily done with the History object, using its static newItem(String historyToken) method:

    private void saveTodoListInHistory() {
                                  
    List todoListClone = new ArrayList();
    Iterator it = todoList.iterator();
    while (it.hasNext()) {
    Todo todo = (Todo) it.next();
    todoListClone.add(todo.clone());
    }
    historyMap.put(String.valueOf(historyToken), todoListClone);
    History.newItem(String.valueOf(historyToken));
    historyToken++;
    }
    In our example, you stored the application state in a map so it can be found using the history token. Note that you used a number as the history token, but that any string could be used instead.

    Deploying Your Web App

    To deploy a Web application made with GWT, you compile the client-side code, package the result inside the .war file of your Web application, and then deploy the .war file on your favorite application server, OC4J.

    Compiling the Client-side Code

    There are several ways to compile your client-side code. When you used the applicationCreator script, GWT creates a shell script named TodoApp-compile. You can launch it from the command line. Like TodoApp-shell, it’s a fine way to compile the application; however, you may prefer to launch it directly from within JDeveloper.

    Another way to compile your code is to execute your application in Hosted mode so it can be done directly from JDeveloper. The toolbar of your application’s window contains a compile/browse button, like this:

    figure 13

    At the end of the compilation process, your default Web browser will open so you can test the result. The window of the GWT development shell will show if the compilation was successful:

    figure 14

    Regardless of how you compile your code, you’ll find the generated files in the www/otn.todo.TodoApp of your project.

    The last way to compile your code is to use Ant. GWT doesn’t provide a specific Ant task, but you can launch any Java class (such as GWTCompiler) with the standard Java Ant task. First, define the path to include the GWT jars:

                                   
    <path id="project.class.path">
    <pathelement path="${java.class.path}/"/>
    <pathelement location="src"/>
    <pathelement path="/your/path/to/gwt-user.jar"/>
    <pathelement path="/your/path/to/gwt-dev-linux.jar"/>
    <!-- ... -->
    </path>
    Now, define a task dedicated to the compilation of your client-side code:
    <target name="GWTcompile">
                                  
    <java classpathref="project.class.class.path"
    classname="com.google.gwt.dev.GWTCompiler"
    fork="true">
    <arg value="-out"/>
    <arg value="${gwt.output.dir}"/>
    <arg value="${entry.point.class}"/>
    </java>
    </target>

    Set the gwt.output.dir and entry.point.class variables in a properties file, like this:
    gwt.output.dir=www
                                  
    entry.point.class=otn.todo.TodoApp
    Finally, declare the properties file (here, build.properties) inside your Ant script, like this:
    <property file="build.properties"/>
                                  
    You can directly launch this new target by selecting Run Target GWTCompile in the Context menu of the task:

    figure 15

    The Apache Ant Log window will show the following result:

    GWTcompile:
                                  
    [java] Output will be written into www\otn.todo.TodoApp
    [java] Compilation succeeded

    BUILD SUCCESSFUL

    Deployment in OC4J

    Once you have compiled the application, deploying it under OC4J is just a matter of creating a correct deployment profile. If you followed the steps described earlier, you should already have a default deployment profile. Otherwise, just select File > New... > Deployment Profiles > WAR File, and create a new profile.

    Using your configuration, everything should work out of the box. However, if you encounter any problems, check for the following common mistakes:

    • In Project Properties, in Project Content > Web Application, the HTML Root Directory should be your application’s www directory (where GWT will compile the application for running in Hosted mode).
    • In the deployment profile, in File Groups > WEB-INF/lib > Contributors, the gwt-user.jar should be added. This jar file includes the javax.servlet package from the J2EE specification. This didn’t cause any problems in our example; however, you shouldn’t usually deploy those classes inside a Web application, as they may cause some trouble. If this happens, GWT also provides a gwt-servlet.jar file, which is the gwt-user.jar without the javax.servlet package.
    • The Web application’s context root affects GWT’s RPC mechanism. If your GWT client application is talking to the server, as described in “Data Exchange between client and server using RPC”, it must be able to find the server. That’s the purpose of the endpoint.setServiceEntryPoint("") method that we’ve discussed. In our example, we deployed the application on the root of the server, which is how the GWT shell works by default. But if you deploy the application to the TodoApp Web context (in the deployment profile’s general properties), set the endpoint to /TodoApp/todoListBackupService, not to /todoListBackupService. Don’t forget that this URL should also be correctly mapped in the application’s web.xml file, as described earlier.
    • Assuming that OC4J is correctly installed on your system, deploying the application to the server is simple: just right-click the deployment profile and select Deploy to OC4J.
    The deployed application has two parts:
    • The client-side application is a set of HTML and JavaScript files that were compiled previously. (See the section “Compiling the Client-side Code.”) OC4J serves as a classic Web server, which delivers those files to the user.
    • The server-side application is basically a servlet that handles the RPC communication. Once deployed in OC4J, this servlet can access enterprise resources such as EJBs or JMS providers.
    Performance-wise, serving static resources is very efficient; the main performance bottleneck of our application should come from client/server communication. But thanks to OC4J, we have access to some interesting server-side performance graphs:

    figure 16

    As this graph shows, under normal load (a few requests per second) the server-side part of the application responds in less than 4 ms on average—an excellent result.
    Stéphanie Antoine is a senior J2EE developer working for a major French software consultancy firm. Julien Dubois and Jean-Philippe Retaillé are both J2EE experts and authors; their latest book, Spring par la Pratique (Eyrolles, 2006) is the first French book about the Spring J2EE framework.

    Send us your comments