Skip to main content

skip to main content

developerWorks  >  Open source | Java technology | Information Management  >

Build an Ajax application using Google Web Toolkit, Apache Derby, and Eclipse, Part 4: Deployment

Get your application and the Derby database up and running

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Intermediate

Noel Rappin (noelrappin@gmail.com), Senior Software Engineer, Motorola, Inc.

27 Feb 2007

In the past three articles in this series, you've built a simple but functional Web application using the Google Web Toolkit (GWT). Until now, you've been editing and debugging the application using GWT's hosted mode, which allows you to simulate a Web server environment within your Java™ development tool. Sadly, it's impractical to have all your users download Eclipse just to run your Web application. So, in this article, the fourth in this series, you'll learn how to deploy your GWT application within a Java Web application server and get tips on using the Apache Derby database to drive the GWT.

In this article, you'll use Apache Tomcat as your example servlet container, because it's both widely used and available at no cost. Other servlet containers will behave similarly. You'll often be deploying to an existing server; but if not, the links in the Resources section at the end of this article point you to the Tomcat download location. If you're running the Microsoft® Windows® operating system, Tomcat has a binary installer for Windows that's relatively simple to use. If you're on a Mac or a UNIX® system, there's a compiled version that you can extract and place in a convenient location (/usr/local is common); after setting a few environment variables, you're good to go.

Compile your client code

Broadly speaking, there are two steps to deploying your GWT application in Tomcat.

  1. Gather all the files you'll need and put them where Tomcat can see them.
  2. Make Tomcat aware of all the server-side actions you call from your GWT page.
Check out the Ajax Resource Center, your one-stop shop for information on the Ajax programming model, including articles and tutorials, discussion forums, blogs, wikis, events, and news. If it's happening, it's covered here.

The process has a few more steps than is desirable, and as of this writing there's no official method of automating it. I describe the manual process here. By the time you read this, however, there may be more robust tool support for deployment.

  • Locate your Tomcat installation's root directory. One level down from that directory you'll see a subdirectory called webapps. Every application running within the Tomcat servlet container gets its own directory there. So create a directory called slicr within webapps. The structure of a Java server-side application is set by the servlet standard, and all servlet runners should support the same structure.
  • Within your slicr directory, create a subdirectory called WEB-INF -- and yes, the capitalization is important.
  • To your slicr directory, move both your GWT-compiled JavaScript pages and your normally compiled Java classes. I'll show how to do the Java classes first.
  • Compile your Java code as you normally would, using your integrated development environment (IDE), Apache Ant, or whatever you wish. You have a couple of options at this point:
    • The quickest option is to copy your entire tree of .class files to the Tomcat subdirectory webapps/slicr/WEB-INF/classes, which Tomcat automatically places in the classpath variable of your webapps directory when run.
    • Alternately, you could convert the compiled classes to a JAR file using the tool of your choice, and then place that JAR file in the webapps/slicer/WEB-INF/lib directory. Again, Tomcat places the JAR file in that directory in your classpath variable.

Compile your GWT client files

Next up, compile and move your GWT client files. Because you've done most of your work in hosted mode, you've been able to skip performing this step explicitly to date. The quickest way to compile your code is to use the Compile button from the hosted mode console. But there's another way that might be more convenient for automating.

In Part 1 of this series, you used the GWT applicationCreator script to create your GWT project. At the time, I casually alluded to "a couple of shell scripts" created along with the GWT project files but didn't go into more detail.

One of the shell files created is called Slicr-compile. In Windows, the file also has a .cmd extension. (Generically, of course, it's your project name-compile.) Invoke the file from a command line, or click it depending on your operating system. The script putters around for a while before outputting something like this:

Output will be written into ./www/com.ibm.examples.Slicr
Compilation succeeded


What's happening here is that GWT is compiling all your client-side Java code into JavaScript code. Client-side code, by default, is all the code in your project's client source directory; however, you can explicitly change that directory in your project .gwt.xml file by adding a tag of the form <source path=path/>, where path is the source path you want to add. Note that the default path is no longer included if you add your own path, so if you also want the default path, you must add it explicitly.

The GWT compiler usually converts legal Java code successfully. However, some items will cause problems. Following are some things to be particularly aware of:

  • GWT client code must be compatible with Java 1.4. That means no generics, no autoboxing, and no new-style for-each loop. Supposedly, Java 1.5 compatibility is planned for the future.
  • Only a minimal subset of the Java Standard Library is supported. Supported library classes are limited to the java.util and java.lang packages. Not all of these packages are supported. In particular, the java.lang.reflect package is not supported. As you saw in Part 2 of this series, this restriction means that you must put items like database code in other parts of your system.
  • If you use regular expressions, they are interpreted at run time using the JavaScript rules, not the Java rules.
  • Java serialization is not supported. The GWT remote procedure mechanism is used instead, as discussed in Part 3 of this series.
  • There are differences in the definition of floating-point numbers and long variable types. Calculations that require strict floating-point semantics should be handled on the server side.
  • The GWT compiler ignores Java assert statements. Also ignored are synchronized declarations, as the JavaScript interpreter does not support threading.

Investigate the compilation output

Assuming that your Java code passes those requirements and your compilation is successful, you can follow the output of the compile script and investigate the ./www/com.ibm.examples.Slicr directory, as shown in Listing 1. Some of your file names may differ.


Listing 1. Output from GWT compilation
	
1A0A627040909C0818A7A71B13246DCD.cache.html
1A0A627040909C0818A7A71B13246DCD.cache.xml
587B8CC6CF487EBD41844000481528BF.cache.html
587B8CC6CF487EBD41844000481528BF.cache.xml
64AF143E1C4C5866446137A8C42B4609.cache.html
64AF143E1C4C5866446137A8C42B4609.cache.xml
B01955141995DDAD97AFC2941024CE4E.cache.html
B01955141995DDAD97AFC2941024CE4E.cache.xml
Slicr.html
com.ibm.examples.Slicr.nocache.html
gwt.js
history.html
tree_closed.gif
tree_open.gif
tree_white.gif

Easy things first: Slicr.html is the HTML page you coded, copied here directly from your public directory. Anything in the public directory will be placed here. The three .gif files are, as you might expect from their names, used by GWT in rendering tree widgets. Because you have no tree widgets in the Slicr application, you can assume that GWT always puts these images in your output. Moving on to the rest of the files with pronounceable names, history.html has some JavaScript code for managing state and preserving Back button behavior. The gwt.js and nocache.html files both contain more or less boilerplate code designed to start and load your GWT application properly.

Which brings you to the files with the hex digit gobbledygook names. There are six HTML/XML pairs. Open the .html files and you'll see a lot of highly obfuscated JavaScript code, as shown in Listing 2, chosen at random.


Listing 2. JavaScript code
	
function ob(pb,qb){z();pb.F = qb;return pb;}
function rb(sb,tb,ub){z();sb.D = ub;sb.F = tb;return sb;}
function vb(){}
_ = vb.prototype = new f();_.jb = C;_.hb = E;_.i = 'java.lang.Throwable';
_.j = 1;_.D = null;_.F = null;function wb(xb){mb(xb);return xb;}
function yb(zb,Ab){ob(zb,Ab);return zb;}
function Bb(Cb,Db,Eb){rb(Cb,Db,Eb);return Cb;}

Hope that's clear. That's actually your nice, neat Java code compiled to JavaScript code by the GWT compiler. There are five HTML/XML pairs, one for each of the major Web browser rendering engines: Firefox/Gecko (old and new versions), Windows Internet Explorer, Opera, and Safari. The XML files manage some data type mapping so that the correct data types for that engine are used. The obfuscation is there to compress the size of the text file that has to be sent to the browser. When a user hits the GWT page from a browser, the JavaScript code in the boilerplate pages automatically retrieves and loads the correct version of your code for the user's browser.

To deploy your GWT pages, all these files from the www/com.ibm.examples.Slicr directory must be copied into the Tomcat Home/webapps/slicr directory. That takes care of the client side, now onto the server side.



Back to top


Deploy the server side

If you've done servlet development before, then this part of the GWT process should be familiar. The server-side code you've written is just another servlet application and is deployed using the Servlet standard.

First, you must compile all your Java code using a plain, ordinary Java compiler. At this point, you have two options:

  • You can place all the .class files in the Tomcat Home/webapps/WEB-INF/classes directory.
  • Alternately, you can combine all your .class files into a .jar file and place that file in the Tomcat Home/webapps/WEB-INF/lib directory.

The compiled code should include the client-side code you've already compiled using GWT -- remember, you use some of those client classes on the server side to facilitate data transfer.

You must also put any third-party libraries you use in the same /lib directory. This directory always includes the file gwt-servlet.jar, which is itself included with the GWT distribution. This file contains all the GWT user files that your application needs.

Note: The original distribution of GWT did not include this file. However, you still may see Web deployment instructions that involve hacking the gwt-user.jar file to remove servlet classes that would interfere with Tomcat. If your GWT distribution is up-to-date, this step is not necessary.

In this case, you also need the derby.jar file, which is part of the Derby distribution and which contains the Derby database classes you need. If you want to transfer the Derby database so as not to lose the toppings data you put into it, simply place the slicr directory database that Derby created in Part 2 of this series. (If you followed the directions in Part 2, this directory should be under your project top level at the same level with the /src directory.) It doesn't matter where you put the directory, but the line in the ToppingServiceImpl class that defines the JDBC URL for Derby must reflect that location:

public static final String PROTOCOL =
"jdbc:derby:[LOCATION OF SLICR DB DIRECTORY]/slicr;";


I placed my Derby database inside the Tomcat webapps/slicr directory, at the same level as the WEB-INF directory, so my code looks like this:

public static final String PROTOCOL =
"jdbc:derby:/usr/local/apache-tomcat-5.5.20/webapps/slicr/slicr;";


Define your server-side calls in web.xml

After your code is visible to the Tomcat servlet container, you must also specifically define all the server-side calls from your GWT application in terms that the Tomcat Web server can understand. Doing so involves defining these server-side calls as servlets in the Tomcat application's web.xml file. Essentially, for each servlet defined in your gwt.xml file like this:

<servlet path="/toppings" class="com.ibm.examples.server.ToppingServiceImpl"/>

you must create a <servlet> and a <servlet-mapping> tag in the web.xml file. Listing 3 shows the entire web.xml file for your GWT project, containing both of these tags for your one ToppngService servlet.


Listing 3. Web.xml
	
<?xml version="1.0" encoding="UTF-8"?> 
<web-app> 
    <servlet> 
        <servlet-name>ToppingService</servlet-name> 
        <servlet-class>
            com.ibm.examples.server.ToppingServiceImpl
        </servlet-class> 
    </servlet> 
    <servlet-mapping> 
        <servlet-name>ToppingService</servlet-name> 
        <url-pattern>/toppings</url-pattern> 
    </servlet-mapping> 
</web-app>    

Within the web.xml file, the two pieces of information given in your gwt.xml file are split into two different tags, as part of the Java make-everything-as-verbose-as-possible initiative. The <servlet> tag takes the fully qualified class name for the servlet, and the <servlet-mapping> tag takes the URL path name as you defined it in the GWT file. The two are unified through the common servlet-name attribute, which can be anything you like as long as you're consistent. However, it's probably best to use a simple naming convention, such as the GWT name of the actual service.

Creation of this file is, of course, eminently automatable by any number of methods ranging from pure text manipulation to XML Document Object Model (DOM) manipulation. When you've written this file, place it inside your Tomcat WEB-INF directory. At this point, the Slicr deployment is complete, and you can test the application by starting Tomcat and typing in the URL, which will be something like http://localhost:8080/slicr/Slicr.html. If successful, you'll see the Slicr page just as it was at the end of Part 3 of this series.

Troubleshooting deployment problems

ProblemCause
You don't see anything at all when you type in the URL.Most likely the cause is that the Slicr.html page is not in the right place. If you just get Welcome to Slicr but none of the GWT widgets, you most likely didn't properly place the GWT JavaScript files.
You see the left side of the page but nothing on the toppings pane except the headers.This means that the server call failed. You'll have to go to the Tomcat logs to diagnose this problem properly (or alternately, change the OnFailure() method in the callback to print an error message to the pane). The first possibility is that you don't have your Slicr Java class files in place, which is preventing the servlet from even loading. (This might also happen if the web.xml file isn't set up properly.)
You encounter a Derby failure.Make sure that the JDBC URL matches the location of the Derby data directory.

Now that I've described this entire process, you can see that although there are many steps, none of them is particularly complex. I strongly recommend automating your deployment as much as possible by using scripts, Ant tasks, or any other means that work for your project. You'll see one example in Resources, and the various Java IDEs are increasingly adding GWT support, including deployment. Having a one-button deployment saves you a lot of headaches.



Back to top


More to explore

Over the course of this article series on GWT, you've built a simple Web application that demonstrates how you can use GWT with a database back end to create a robust Web application with rich client behavior. Even after four articles, you've only scratched the surface of what GWT has to offer. Powerful features -- such as JUnit test integration, using other Web services through JavaScript Serialized Object Notation (JSON) data exchange, and the new GWT internationalization features -- are well worth your time to check out. GWT development continues to grow, and new features and add-on tools are being added all the time. I hope that you'll be able to take a look around and find the tools you need to build the application you want.



Resources

Learn

Get products and technologies

Discuss


About the author

Noel Rappin, a Ph.D. from the Graphics, Visualization, and Usability Center at the Georgia Institute of Technology, is a senior software engineer at Motorola. He is also the coauthor of wxPython in Action and Jython Essentials. You can check out Noel's blog at 10printhello.blogspot.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top


Cloudscape, IBM, and the IBM logo are a registered trademarks of IBM in the United States, other countries or both. Java is a trademark of Sun Microsystems in the United States and other countries. Microsoft and Windows are trademarks of Microsoft Corp. in the United States and other countries. UNIX is a trademark of The Open Group in the United States and other countries. Other company, product, or service names may be trademarks or service marks of others.