Getting Started Tutorial

This document is a short but effective tutorial on how to write your own servlets for Tynamo™-aJile.

Below is a step-by-step guide that describes the entire process, from downloading the tools, to accessing your servlet or servlets from an HTTP client. More details can be found in the Server Configuration document.

Table of Steps

  1. Pre-Setup
  2. Download Tynamo™
  3. Write Servlets
  4. Update the Build Configuration
  5. Build Using Ant
  6. Update the Servlet Configuration
  7. Additional Configuration
  8. Build using JemBuilder
  9. Upload using Charade
  10. Enjoy Your Servlets!

0. Pre-Setup

Before beginning this sequence of steps, it is important to have all the necessary tools and utilities installed. Thus, this step "0" is here to provide instruction on this initial setup, if needed.

There is one tool, besides the JDK, that the build process uses. This is the Ant utility from The Jakarta Project. As of this writing, the latest version of Ant is 1.6.1.

It is assumed that you have already installed the aJile tools to enable installation of an application on the development board. As of this writing, the latest version of these tools is 3.16.09.

Briefly, Ant needs the ANT_HOME and JAVA_HOME environment variables set correctly, and the bin subdirectory of the Ant installation added to the path.

[Top]


1. Download Tynamo™

Download the latest version of Tynamo™ from tynamo.qindesign.com. (This is the current homepage.) The easiest way to install the package is to create a directory, such as 'tynamo-aJile-1.0', and unzip the file into this location.

[Top]


2. Write Servlets

This step demonstrates how to write a simple servlet. There is much literature on this subject, for example in the Documentation section of the Servlets home page, so a relatively small example is presented here. Please remember, however, that Tynamo™ complies with the Servlet 2.2 specification, and not 2.3 or above.

import java.io.IOException;
import java.util.Calendar;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Simple servlet that shows information about the server.
 *
 * @author Shawn Silverman
 */
public class ServerInfoServlet extends HttpServlet {
    /**
     * Process a GET request.
     *
     * @param req the request object
     * @param resp the response object
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        // Set up the response

        resp.setContentType("text/html");
        ServletOutputStream out = resp.getOutputStream();

        out.print("<html><head><title>Server Info Servlet</title>");
        out.print("<style>body{font-family: Verdana,sans-serif}</style></head><body>");
        out.print("<h1>Server Information</h1>");
        out.print("<p>This servlet shows information about the server.</p>");

        // Get the servlet context

        ServletContext context = getServletContext();

        out.print("<table border=\"0\">");

        // Server info

        out.print("<tr><td>Server is</td><td><strong>");
        out.print(context.getServerInfo());
        out.print("</strong></td></tr>");

        // Server uptime

        out.print("<tr><td>Server uptime is</td><td>");
        Long startTime = (Long)getServletContext().getAttribute(
                "com.qindesign.http.startTime");
        if (startTime != null) {
            out.print("<strong>");
            printElapsedTime(out, System.currentTimeMillis() - startTime.longValue());
            out.print("</strong>");
        } else {
            out.print("&lt;unknown&gt;");
        }
        out.print("</td></tr>");

        out.print("<tr><td bgcolor=\"Gray\" height=\"2\" colspan=\"2\"></td></tr>");

        // Attribute names

        out.print("<tr valign=\"top\"><td>Context attributes:</td><td>");
        Enumeration e = context.getAttributeNames();
        if (e.hasMoreElements()) {
            out.print("<ul style=\"margin-left: 1.5em\">");
            do {
                String name = (String)e.nextElement();
                out.print("<li><code>");
                out.print(name);
                out.print('=');
                out.print(String.valueOf(context.getAttribute(name)));
                out.print("</code></li>");
            } while (e.hasMoreElements());
            out.print("</ul>");
        } else {
            out.print("&lt;none&gt;");
        }
        out.print("</td></tr>");

        out.print("</table>");

        // Print a footer with the current time

        out.print("<hr /><address>This page was generated on <strong>");
        out.print(Calendar.getInstance().toString());
        out.print("</strong>.</address>");

        out.print("</body></html>");
    }

    /**
     * Prints the elapsed time in "d'd', HH:mm:ss" format.
     *
     * @param out the output stream
     * @param time the elapsed time, in ms
     */
    private static void printElapsedTime(ServletOutputStream out, long time)
        throws IOException
    {
        // Days

        out.print(time / (1000*60*60*24));
        time %= 1000*60*60*24;
        out.print("d, ");

        // Hours

        long l = time / (1000*60*60);
        if (l < 10) out.write('0');
        out.print(l);
        time %= 1000*60*60;

        out.write(':');

        // Minutes

        l = time / (1000*60);
        if (l < 10) out.write('0');
        out.print(l);
        time %= 1000*60;

        out.write(':');

        // Seconds

        l = time / 1000;
        if (l < 10) out.write('0');
        out.print(time / 1000);
    }
}

[Top]


3. Update the Build Configuration

Open the build.properties file in the root of your Tynamo™ installation. The first thing you need to do is change the cldc.classes and ajile.classes properties to point to the correct classes. For example:

cldc.classes=/Java/aJile/Runtime_cldc/classes.jar
ajile.classes=/Java/aJile/Runtime_cldc/Rts

Note: if you use backslashes (\) as the file separator, then you must use them in pairs (eg. cldc.classes=C:\\Java\\aJile\\Runtime_cldc\\classes.jar). This applies to all of the build properties.

Next, change src.paths to point to the root of your servlet source code. For example, if you have a directory named src underneath /projects/myapp, then change src.paths to read:

src.paths=/projects/myapp/src

Personally, I like to place a src/ directory underneath the root of the Tynamo™ installation. If you have done this, then src.paths should read something like:

src.paths=/tynamo-ajile-1.0/src

(This assumes that the Tynamo™ installation resides at /tynamo-ajile-1.0.)

After this, add an Ant-style list of source files to the src.files property. For the example above, this would read:

src.files=ServerInfoServlet.java

Note that forward slashes (/) (and colons (:) for the src.paths path separator) should always be used for these paths, even on Windows systems.

More src.files Examples

If, say, you have more than one source file in the package com.entity.myapp, then src.files would read as:

src.files=com/entity/myapp/*.java

You can even include more than one subpackage by doing this:

src.files=com/entity/myapp/**/*.java

Please consult the Ant documentation for more details about specifying files.

[Top]


4. Build Using Ant

Build your servlets and the server using Ant. In many cases, all you need to do is execute the ant command from the commandline, in the same place as your Tynamo™ installation. Ant will automatically look for the included build.xml file, use your new build configuration, and then proceed with the build.

[Top]


5. Update the Servlet Configuration

Open the servlets.props file in the res/config/ directory of your Tynamo™ installation. You must provide a mapping, a classname, and any initialization arguments for each servlet. Further details can be found in the Servlet Configuration Properties document. For our example, one possibility for these settings is:

ServerInfo.mapping=/servlet/ServerInfo
ServerInfo.class=ServerInfoServlet

We have just indicated to the web server that any request for the path /servlet/ServerInfo will access our example servlet. Also, it is worthwhile to note that this class does not exist inside of a package, so the full classname is just the classname itself: ServerInfoServlet as oppsed to com.widgets.ServerInfoServlet.

[Top]


6. Additional Configuration

For additional web server configuration, you are referred to the Configuration document. Most of the options are specified in the JemBuilder project, however, and are detailed in the next step.

Please note that the default value for any configuration property will be used in its absence. For example, the default value of tynamo.server.maxHandlers is 4, so if it is not specified, then a value of 4 will be assumed. This is mentioned because not every property will necessarily be in the JemBuilder project file.

[Top]


7. Build using JemBuilder

This step will walk you through modifying the included Tynamo.ajp JemBuilder project. It will explain what you need to get Tynamo™ running on your board. More advanced options such as PLL configuration, memory setup, and optimization will not be discussed.

  1. In the Project.Properties menu, select your target configuration. If you are using a JStik, decide whether you want to run the server from flash or from RAM. In either case, be sure to select the correct jumper settings on your board. For example, on the JStik, JP3 needs to be "off" to run from flash, and "on" to run from SRAM.
  2. In the Project.Output Files panel, replace the parent of output with the location of your Tynamo™ distribution. For example, if your project is located in /Projects/tynamo-ajile-1.0, then set this value to be /Projects/tynamo-ajile-1.0/output.
  3. In the JVM0.Classpath panel, first replace the parent of bin/tws_core.jar, examples/servlet_examples.jar, and res with the location of your Tynamo™ distribution, and second, add <path_to_distribution>/classes — the location of the compiled ServerInfoServlet class. Depending on your platform, you may need a different path separator character. For example, on Windows, this needs to be a semicolon (;), and UNIX often uses a colon (:).

    As well, the file separator may change depending on the platform. For example, on Windows it is a '\' character, while on UNIX it is a '/' character. Be sure to use the correct one in all of the paths, replacing them as necessary.

    Also, if you wish to use the J2ME 1-Wire library (or any other library for that matter), either add it to the classpath, or add it to the available libraries in the Tools.Libraries menu and add it to the "Libraries" list.

  4. The JVM0.Memory panel has some noteworthy options. If ever you get stack overflow exceptions, try increasing the "New Thread Stack Size". If you get out of memory exceptions, then try increasing the "Initial Heap Size".
  5. Configure the appropriate properties in the JVM0.Properties panel. Please consult the Configuration document for a description of each option. A default set of properties is provided for you, however.
  6. The JVM0.forName panel contains a list of all classes that need to be accessible via a Class.forName call. This list, at the very least, must include the classname of each servlet. The Configuration document discusses this topic in more detail. A default list is provided for you, although you need to add ServerInfoServlet.

    If you are not accessing the 1-Wire API, either with the 1-Wire Explorer demo or with your own code, then you need to remove any class from this list that has "onewire" in it (plus any example class that ends with "Include", as these are part of the OneWireServlet example set). Additionally, if the classpath (step 3) or library list does not include this API, then you must remove these classes or there will be build errors.

  7. The JVM0.Resources contains a list of all the HTTP-accessible resources on the server. Additionally, it contains the servlet and MIME type configuration files. Add more resources here if you wish other pages or images, etc., to be available. The Configuration document describes this topic further.

    Of note is that there is no leading slash, and that forward slashes are always used, regardless of the platform used with JemBuilder.

  8. Finally, ensure that the JVM0.Ethernet.IP Addresses panel driver has the correct IP configuration. Specifically, you need to set the "IP Address", "Net Mask", and "Gateway Address". If you are running the 1-Wire demo servlet, then also be sure to install the com1 driver in the Project.Drivers menu.

Lastly, choose Build in the Project menu or press the "Build Project" button to build a binary for use with Charade.

[Top]


8. Upload using Charade

Hook up your device and start charade. First, ensure that the correct processor is selected in the Device menu. This will usually be "aJ-100 (port 378)". If your JTAG adapter is on another parallel port then select the appropriate choice.

Ensure that you have the correct jumper settings in place for a RAM or flash load, then select the File.Execute menu. Navigate to your Tynamo™ distribution, and then to the output/ directory. Next, select the load.sod file produced by JemBuilder.

After the binary is finished loading, hit the Go button!

[Top]


9. Enjoy Your Servlets!

Use a web browser or some other HTTP client and connect to your web server:

http://{device address}/servlet/ServerInfo

Enjoy!!

[Top]