![]() |
iPlanet Application Server 6.5 SP1, Enterprise Edition Programmer's Guide (C++) |
Updated: November 25, 2002 |
Running and Debugging Applications
This chapter describes how to set up a test version of your application, as well as how to use the debugging tools in your C++Java development toolkit.
The following topics are included in this chapter:
Getting Ready to Run an Application
Before you can execute the AppLogic objects in your application, you must set up a test version of your application. This involves copying your application files to the appropriate locations and registering the AppLogics, other code modules, and security information needed in the application. For the purposes of testing, you will probably set up the application on a single iPlanet Application Server.
This manual does not describe application deployment in detail. In general, the procedure for setting up an application for testing is similar to that for deploying production applications. This section describes only those procedures that are specific to setting up an application for testing.
Alternatively, if you are using iPlanet Application Builder, you can deploy applications using its deployment feature. This procedure is described in User's Guide.
Compiling Applications
This section assumes that you are already familiar with creating makefiles and compiling source files on your development platform. It also assumes that you have already installed the entire Calhoops sample application on your development system using the iPlanet Application Server installation procedure described on the product CD.
This section lists relevant libraries to link to and describes creating a makefile for your AppLogic, using examples of makefiles from the Calhoops sample application for the Sun Solaris, Hewlett-Packard HP-UX, and Microsoft Windows NT platforms.
Setting the GX_ROOTDIR Environment Variable
Before compiling, you need to set the $GX_ROOTDIR environment variable to point to the root directory for the iPlanet Application Builder. For instructions on how to do this, see the system documentation for your particular development platform.
Creating a Makefile
Use your C++ application development tools to generate the makefile for your project. The following examples show the makefile for the Calhoops sample application on the Sun Solaris, Hewlett-Packard HP-UX, and Microsoft Windows NT platforms.
# Sample makefile for C, C++ applogics
# Run 'make debuggable' or simply 'make'
# to build shared library with debug info.
# Run 'make release' to build optimized shared library
OBJS = calhoops.o # list of all object files to be generated
SHO = libcalhoops.so # name of shared object file to generate
debuggable := TARGET = debuggable
CPPFLAGS = -KPIC -mt -DUNIX -DGXPUBLIC_BUILD -D$(PLATFORM) $(DEBUG) $(INCLUDES)
CFLAGS = -KPIC -mt -DUNIX -DGXPUBLIC_BUILD -D$(PLATFORM) $(DEBUG) $(INCLUDES)
SHOFLAGS = -G -Bsymbolic -mt -z text -L $(LIBDIR)
[ -d $(LIBDIR) ] && cp $(SHO) $(LIBDIR)
$(CPP) $(SHOFLAGS) -o $(SHO) $(OBJS) -lgxagent -lgxidl -lgxutil
@rm -f $(SHO) $(LIBDIR)/$(SHO)
# Sample makefile for C, C++ applogics
# Run 'make debuggable' or simply 'make'
# to build shared library with debug info.
# Run 'make release' to build optimized shared library
OBJS = calhoops.o # list of all object files to be generated
SHO = libcalhoops.sl # name of shared object file to generate
debuggable := TARGET = debuggable
CPPFLAGS = +Z +a1 -DUNIX -D$(PLATFORM) -DGXPUBLIC_BUILD $(DEBUG) $(INCLUDES)
CFLAGS = +Z -Ae -DUNIX -D$(PLATFORM) -DGXPUBLIC_BUILD $(DEBUG) $(INCLUDES)
SHOFLAGS = -b -q -Wl,+s,+b:,+vshlibunsats $(CPPFLAGS) -L $(LIBDIR)
[ -d $(LIBDIR) ] && cp $(SHO) $(LIBDIR)
$(CPP) $(SHOFLAGS) -o $(SHO) $(OBJS) -lgxagent -lgxidl -lgxutil
@rm -f $(SHO) $(LIBDIR)/$(SHO)
Microsoft Windows NT
PROJECT=calhoops.dll
##############################################################
CC_FLAGS =$(MYCFLAGS) /c /nologo /MTd /W3 /GX -DWIN32 -DWINDOWS
CC_FLAGS_DBG=/Od /Zi /Gm -DDEBUG -D_DEBUG
LINK_FLAGS =$(MYLFLAGS) /MAP /subsystem:windows /dll /incremental:no
LINK_FLAGS_DBG=/DEBUG:FULL /DEBUGTYPE:BOTH
INCLUDE=$(KIVA_ROOT)\include;$(INCLUDE)
LIB =$(KIVA_ROOT)\lib\c;$(LIB)
LIBS=gxagent.lib gxutil.lib gxidl.lib kernel32.lib user32.lib uuid.lib
CC_FLAGS=$(CC_FLAGS) $(CC_FLAGS_DBG)
LINK_FLAGS=$(LINK_FLAGS) $(LINK_FLAGS_DBG)
CC_FLAGS=$(CC_FLAGS) $(CC_FLAGS_REL)
LINK_FLAGS=$(LINK_FLAGS) $(LINK_FLAGS_REL)
$(LINK) $(LINK_FLAGS) $(PROJECT_OBJS) /OUT:$(PROJECT) $(LIBS)
Placing Files on the iPlanet Application Server
This section uses the following abbreviations to refer to directories on your file system:
- $GX_ROOTDIR is the root directory where you installed the iPlanet Application Builder.
- $APP_ROOTDIR is the root directory where you store AppLogic files for a specific application or project. We recommend that you make this a subdirectory under the GXApp directory:
When placing shared libraries and HTML template files (for HTML-based clients) on your iPlanet Application Server, consider storing them in the following locations, where $GX_ROOTDIR is the Netscape Application Server root installation directory:
For example, the Calhoops sample application shared library files might be stored in the following locations:
Placing Files on the Web Server (HTML Client)
When placing web pages and graphics files on your Web server, consider storing them in the following locations, where <Code>$WS_DOCROOTDIR is the document root directory of the web server:
For example, the query selection form for the Calhoops sample application (index.html) might be in the following path:
<Code>$WS_DOCROOTDIR/GXApp/CCalhoops/index.html
Registering Code And Security Information
Before you can execute your application, you must set up a test version. As one of the steps in this procedure, you must register certain application items with the iPlanet Application Server. When setting up an application for testing, you might need to register any of the following types of items with the iPlanet Application Server:
By registering users, user groups, and ACLs, you can set up security for the application. During testing and initial deployment, you must define these items yourself if your application includes security features, such as calls to lLoginSession( ). During production deployment, the system administrator can also manage the security information, using the iPlanet Application Server Administrator tools.
If you are using the iPlanet Application Builder, you can use its deployment feature to register code for testing. This procedure is described in User's Guide.
If the deployment tools are not available to you, you can register code using the iPlanet Application Server utilities, as described in the next section.
Using Utilities to Register Application Information
The iPlanet Application Server maintains a record of registered application items in local registry storage. You can use the kreg utility to populate the registry. To do so, edit one or more files with a .gxr extension. These files are the input to kreg.
To register code or security information using utilities
- For an AppLogic object or other code module, you must generate a unique GUID. To do so, run the kguidgen utility from a command line or window by typing the following command:
kguidgen
This utility returns a random, unique GUID which you can copy and paste.
- Add lines to the .gxr file for the items you want to register. The syntax for each type of item is given later in this section. Each item uses four lines.
- Make sure you assign a unique name to the item. Unlike the GUIDs, which are sure to be unique since they are generated automatically, there is a possibility for duplicates when you assign names yourself. For example, prefix the names of your AppLogics with the application name to reduce the possibility of name collisions.
- For an AppLogic object or other code module, paste in the GUID that was generated by kguidgen.
- Run the kreg utility from a command line or window using the following syntax:
kreg fileName.gxr
AppLogic .gxr Syntax
The entry in a .gxr file to register an AppLogic object uses the following syntax (the portion from AppLogic to group is all on one line):
AppLogic name [:type=cj][:enable=y|n][:encrypt=y|n]
[:lb=y|n][:descr[:AppName;group;...]]
GUID [:server;...[acl=user,[!]EXECUTE;...]]
The items in the syntax are as follows:
- name: Name of the AppLogic object.
- :type=cj: Optional letter cj to indicate that the AppLogic object is written in C++Java.
- :enable=y|n: Optional flag to indicate whether the AppLogic is enabled.
- :encrypt=y|n: Optional flag to indicate whether the communications to the AppLogic are encrypted.
- :lb=y|n : Optional flag to indicate whether sticky load balancing is set.
- :descr: Optional description of the AppLogic, which will appear in the Application Administrator.
- :AppName;group;...: Optional semicolon-separated list of groups to which the AppLogic belongs. The first group should be the name of the application.
- Globally unique identifier (GUID) that was generated by kguidgen.
- :server;...: Optional semicolon-separated list of server descriptions. Each server description uses the following syntax:
<SERVER_IP_ADDR>:<SERVER_IP_PORT>[=<SERVER_FLAGS>]
SERVER_IP_ADDR is a decimal-dotted IP address, such as 192.23.43.15. SERVER_IP_PORT is the Executive Server port number, in decimal. SERVER_FLAGS is an optional decimal number. The flags, in hexadecimal, are 0x8000000 to set sticky load balancing and 0x00000001 to set the enable flag. Note that you can turn these on using the lb and enable flags on the first line.
- acl=user,[!]EXECUTE;...: Optional semicolon-separated list of access control list (ACL) entries, to specify which users can execute the AppLogic. Each ACL entry uses the following syntax:
user,[!]permission
User is the name of a User or UserGroup, as specified by the system administrator. Permission is an operation name. For AppLogics, EXECUTE is the only operation that is checked automatically by the system. An exclamation point in front of EXECUTE means the user or user group can not run the AppLogic.
- Class path to the AppLogic object. For increased portability, it is advisable to use relative paths in the .gxr file.
- Path to AppLogic object. For cross-platform compatibility, you can omit the extension of the file (such as .dll or .so) and, on UNIX platforms, you can also omit the lib prefix of the file. For increased portability, it is advisable to use relative paths in the .gxr file.
- (Optional) Comments. Each line can end with a comment preceded by the vertical bar character |.
Example
The following lines show the .gxr file entry for an AppLogic object (the portion from AppLogic to digibanker is all on one line):
AppLogic CalculateBalancesLogic:Updates account balance
{e248ecd0-9bfd-bc32-00a024d1709f}
AppLogic CalculateBalancesLogic:Updates account balance
{e248ecd0-9bfd-bc32-00a024d1709f}
Code Module .gxr Syntax
The entry in a .gxr file to register a code module (that is not an AppLogic object or an iPlanet Extension) uses the following syntax:
Module name [:type=cj][:descr[:AppName;group;...]]
The items in the syntax are as follows:
- :type=cj: Optional letter cj to indicate that the module is written in C++Java.
- :descr: Optional description which will appear in the Application Administrator.
- :AppName;group;...: Optional semicolon-separated list of groups to which the module belongs. The first group should be the name of the application.
- Globally unique identifier (GUID) that was generated by kguidgen.
- Class path to the code module. If the path to a Java wrapper, the C++ DLL is on the next line. For increased portability, it is advisable to use relative paths in the .gxr file.
- Relative path to the code module. For cross-platform compatibility, you can omit the extension of the file (such as .dll or .so). For increased portability, it is advisable to use relative paths in the .gxr file.
- (Optional) Comments. Each line can end with a comment preceded by the vertical bar character |.
Example
The following lines show the .gxr file entry for a code module:
Module DigiBank CICS Integration:type = c
{e248ecd0-9bfd-bc32-00a024d1709f}
{e248ecd0-9bfd-bc32-00a024d1709f}
User .gxr Syntax
The entry in a .gxr file to register a user has the following syntax:
The items in the syntax are as follows:
- Password: The user's password.
- group;...: Optional semicolon-separated list of groups to which the user belongs. These groups are defined elsewhere in the .gxr file, using the syntax described later in this section.
- (Optional) Comments. Each line can end with a comment preceded by the vertical bar character |.
Example
The following lines show the .gxr file entry for a user:
DigiBankUsers;DigiBankAdministrators
User Group .gxr Syntax
The entry in a .gxr file to register a user group has the following syntax:
The items in the syntax are as follows:
- (Optional) Comments. Each line can end with a comment preceded by the vertical bar character |.
Example
The following lines show the .gxr file entry for a user group:
ACL .gxr Syntax
The entry in a .gxr file to register a named access control list (ACL) uses the following syntax:
The items in the syntax are as follows:
- user,[!]permission;...: Optional semicolon-separated list of ACL entries, to specify which users can perform operations. Each ACL entry uses the following syntax:
user,[!]permission
User is the name of a user or user group, as specified by the system administrator. Permission is an operation name, such as EXECUTE, READ, or WRITE . An exclamation point in front of the permission means the user or user group can not perform that operation.
- (Optional) Comments. Each line can end with a comment preceded by the vertical bar character |.
Example
The following lines show the .gxr file entry for an ACL:
DigiBankAdmin,ADMIN;DigiBankPartner,!READ
Saving and Restoring Registry Configurations
he iPlanet Application Server maintains a record of registered application items in local registry storage. You can save and restore snapshots of the registry by using the kreg utility. You might want to do this for the following reasons:
- More easily bring up secondary, replicated servers.
- More easily bring up replicated engines or control sets.
- Save, replicate, and manually synchronize registry information about users, user groups, ACLs, AppLogics, and iPlanet Extensions across multiple machines.
- Debug administration settings.
- Remotely view and debug a configuration.
- Allow various groups in your organization to swap between saved configurations, especially if certain registry configurations are required for certain tests, such as load balancing, partitioning, and stress testing.
- Replicate AppLogic information to the Web server tier. This supports better AppLogic load balancing from the Web server. It also allows encryption of AppLogic requests on a per-AppLogic basis between a Web server and Executive Server.
To Save the Registry
To save a snapshot of the current registry settings, run the kreg utility from a command line or window using the following syntax:
kreg -save fileName key1 [key2...]
The fileName is the file in which the registry settings are saved. The key is the path to a registry key, starting from the root key. For example:
kreg -save mytest.data SOFTWARE\KIVA\Enterprise\2.0\CCS0\DAE
To Restore the Registry
To save a snapshot of the current registry settings, run the kreg utility from a command line or window using the following syntax:
kreg -load fileName [fileName2...]
The fileName is the file in which the registry settings were saved. For example:
Debugging with Third-Party Tools
You can test and debug AppLogic objects using the debugging tools in your C++Java development toolkit. The tools available vary depending on the machine and operating system you are using. iPlanet Application Builder integrates with several debugging tools.
The following steps give a general outline of the debugging process. Specific procedures for each debugging tool follow.
General steps to debug AppLogic
- Compile the AppLogic using the debug option.
For example, in many compilers, the -g flag enables the debug option.
- Start your debugging tool.
For example, on Microsoft Windows NT, you might use msdev. On UNIX, you might use dbx.
- Determine the process ID of the C++ Server process you want to debug.
For example, on Microsoft Windows NT, use the Task Manager. On UNIX, use the ps command.
- Using this process ID, attach to the C++ Server process from within your debugging tool.
For example, if you are using msdev on Microsoft Windows NT, use the menus. If you are using dbx on UNIX, use the command attach PID.
Note: The AppLogic you are trying to debug may not yet be loaded into the C++ Server. Most debugging tools will still allow you to set the breakpoint in the AppLogic before it has been loaded. If not, execute the AppLogic once so that it is loaded.
- Set a breakpoint in your AppLogic.
For example, the beginning of the execute( )Execute( ) method is often a logical place for a breakpoint.
- At the breakpoint, begin stepping through your AppLogic code.
Debugging with Symantec Visual Café Pro 2.0
AppLogic objects can be debugged in Visual Café Pro by creating an Empty Project whose Main Class invokes the Java engine (com.kivasoft.engine.Engine) that would normally be launched by the Netscape Application Builder Runtime Environment. The project must also include the code file(s) of the AppLogic you want to debug. Set your breakpoints in these files, especially in their execute( ) methods. Shut down the Java window in the Netscape Application Builder Runtime Environment, and then launch your project from within Visual Café Pro using the Project menu or pressing F5.
You will also need the Engine.class file that needs to be referenceable from the debugger (Café cannot launch a class file within a JAR).
1. Select File - New Project....
- Open Visual Café Pro.
2. In the New Project dialog box, choose Empty Project.
3. For Project Type, select Application - A program that requires java.exe to run
- Select Project - Options...
4. For Main Class, type com.kivasoft.engine.engine
5. For Program arguments, type -d
7. Add the \kiva\kds\apps directory and \kiva\kds\lib\java\kfcjdk11.zip file to your Class files (you must manually type the zip file name in order to do this)
8. Start the Netscape Application Builder Runtime Environment, and shut down the Java engine once initialization is complete.
- Add the source files you wish to debug into your Project, perhaps by using Insert - Files into Project, and set appropriate breakpoints.
9. Use Project - Run in Debugger or the F5 key to launch the Java engine.
10. Use Window - Messages to view the Java server status, and verify that 'ready: 11001' appears.
11. Bring up a suitable form in a Web browser or somehow cause your AppLogic to execute, and debug normally.
Debugging with Borland JBuilder
AppLogic objects can be debugged in JBuilder by creating a project whose main class simply invokes the main( ) method of the com.kivasoft.engine.Engine class that would normally be launched by the Java Server. The project must also include the code file(s) of the AppLogic you want to debug. Set your breakpoints in these files, especially in their execute( ) methods. Shut down the Java window in the Netscape Application Builder Runtime Environment, and then launch your project from within JBuilder using the Start/Restart menu item or button.
You will also need some dependency files, in JBuilder's proprietary format, containing information about the class hierarchies in the com.kivasoft.* packages, so that JBuilder can build your project. These are supplied with the Netscape Application Builder and should be put in the myclasses subdirectory of your JBuilder directory.
12. Menu File - New Project....
- Open JBuilder.
13. In the Project Wizard, accept the defaults or change them, as you like.
14. Add the source files of your AppLogic to the project. Use the Directory tab near the bottom left, or any other means that works for you.
15. Also create a file whose main method simply invokes the main method of com.kivasoft.engine.Engine with the -d argument. Assume that this file is called LaunchEngine.java.
16. In the Project tab of this dialog, edit the Source Path and add to it the root of the directory hierarchy where you keep your AppLogics. Caution: this may not be the same as the directory where the source files reside, especially if your Java files contain package statements so that your classes are in a package other than the default package. In JBuilder's online User's Guide, the section "Creating and managing projects" has a subsection "Packages" which explains the correspondence between packages and directories.
- Bring up the Project Properties dialog, either by right-clicking on the project file in the Project pane or by using the main menu's File - Project Properties item.
17. Still in the Project tab, edit the Class Path, and add to it the bin/JDK_1.1 subdirectory of the directory where you installed the Netscape Application Builder Runtime Environment.
18. You may also want to edit the Out Path and add to it the root of the directory hierarchy where you keep your AppLogics.
19. Make sure that, under Compiler Options near the bottom of this tab, Include Debug Information is on.
20. On the Run/Debug tab of this dialog box, set the Default Runnable File to be LaunchEngine.java. There is no need to change the other settings.
21. Double-check that the dependency files exist, as mentioned above. If they do not, the command
bmj -p com.kivasoft.foo -nomakestable -d \tornado\win32dbg\jdk_1.1
22. Use the main Build menu, or right-click the project file, to Make your project. It may also be advisable to use the File - Save Project menu item.
for appropriate values of foo, will create them (the BMJ program is in the bin subdirectory of your JBuilder directory). The dependency files you need are the ones for com.kivasoft, com.kivasoft.engine, and com.kivasoft.applogic.
23. Start the Netscape Application Builder Runtime Environment and shut down the Java engine once initialization is complete.
- Open the code files of your AppLogic and set breakpoints, pressing the F5 key in the source editor pane, choosing the Run - Add Breakpoint menu item, or any other means that work for you.
24. Choose Run - Debug or press the F9 key to start LaunchEngine.
25. Choose Run - Run, select the green triangle in the toolbar of the Project pane, or press Shift-F9, to continue from the breakpoint at the first line of LaunchEngine.main.
26. Wait for the JBuilder console or execution log to proclaim "ready:".
27. Bring up a suitable form in a Web browser or somehow cause your AppLogic to execute, and debug normally.
Debugging with JDK 1.1.x jdb
Debugging under jdb is very simple. Here is an example that sets a breakpoint for the fortune AppLogic:
28. Load GXApp.Sample.Fortune1.
- Execute jdb in a command shell.
29. Stop in GXApp.Sample.Fortune1.execute.
30. Run com.kivasoft.engine.Engine -d.
The java engine will execute (you should see the ready: line), and when the request is received you will hit the breakpoint and stop in the debugger. From this point on, '?' will give you the information you need.
Debugging with Java Workshop 2.0
AppLogic objects can be debugged in Sun's Java Workshop 2.0 by creating a standalone project whose main class is the com.kivasoft.engine.Engine class that would normally be launched by the Java Server. The project must also include the code file(s) of the AppLogic you want to debug. Set your breakpoints in these files, especially in their execute( ) methods. Shut down the Java window in the Netscape Application Builder Runtime Environment, and then launch your project from the Workshop using the Start/Restart menu item or button.
31. Choose Project - New... (or open Project Manager and File - New - Project).
- Open JWS.
32. Any name, standalone, no GUI; Next>
33. The directory where your AppLogic source files reside; Yes; Next>
34. Add the Java files of your AppLogic; Next>
35. Main class = com.kivasoft.engine.Engine; Finish>
36. Go to the Build tab.
- Choose Project - Edit
37. "Root directory of class hierarchy": the directory under which .class files compiled from your AppLogic code will be stored. Caution: this may not be the same as the directory you specified when you created the project, especially if your Java files contain package statements so that your classes are in a package other than the default package.
38. Additional classpath: the .JAR file for the Netscape Application Builder Runtime Environment.
JWS follows scrupulously the convention that directory hierarchy should mirror package hierarchy, so that your .class files may appear in a subdirectory of the directory you give. By being aware of this, you can make sure that the class path you give at step 8 below will lead to the correct class files being executed, and that the source path you give at step 6 below will lead to the correct source files being used for source-level debugging. For example, if you create a project file in C:\kiva\kds\APPS\kivaapp\sample, but your classes are in the package kivaapp.sample, specify C:\kiva\kds\APPS as the root directory for the class hierarchy.
39. Go to the Debug/Browse tab.
40. "Source paths to prepend to default": root directory of your AppLogic tree; see the caution at step 3 above.
41. "Main class": verify that this is com.kivasoft.engine.Engine
42. "Java Interpreter Options" must include a -classpath setting with the lib\jws.zip from the directory where you have installed the Java Workshop, the lib\classes.zip from the directory where you have installed your JDK, and the paths given at steps 3 and 4 above. For example (all on one line, and without spaces after the semicolons):
-classpath C:\Java-WorkShop20\JWS\lib\jws.zip; C:\jdk1.1.3\lib\classes.zip; C:\tornado\win32dbg\JDK_1.1; C:\kiva\kes\Apps 44. "Program Arguments": -debug
45. "Main class" and "Java Interpreter Options" will be the same as in the Debug/Browse tab.
46. Start the Netscape Application Builder Runtime Environment and shut down the Java engine once initialization is complete.
- Open the code files of your AppLogic and set breakpoints.
47. Debug - Start/Restart (Shift-F6) or Debug-Resume (F6).
48. Skip past an enormous number of Null Pointer Exceptions, using Debug - Resume (F6) on each one.
49. Bring up a suitable form in a Web browser or somehow cause your AppLogic to execute, and debug normally.
Debugging with MSVC (Version 4.2 or Higher)
To debug code using Microsoft Visual C++, in addition to any projects that you use to build your AppLogic code, you must create a project of type "Console Application" that contains no code files at all, but simply specifies the C++ Server .EXE file of your Netscape Application Server installation as its executable. After invoking your AppLogic once, you will be able to open its source files in the MSVC's editor and set breakpoints in these files.
- File - New- Project Workspace.
- Console Application; any name you like; Location can be any directory, but it will be convenient to use the root directory of your AppLogic tree.
- Select the "Win32 Debug" configuration.
- In "Category", select General.
- As "Executable for debug session" supply the path to the C++ Server .EXE file in your Runtime Environment.
- "Program arguments": -debug (may not be necessary).
- In "Category", select Additional DLLs.
- In the Modules list, add one or more DLLs from your AppLogic and check the boxes to the left of their names.
- Start the Netscape Application Builder Runtime Environment and shut down the C engine once initialization is complete.
- "One or more files are out of date ...?": choose No.
- "One or more breakpoints cannot be set ....": choose OK.
- "First-chance exception ....": choose OK.
- "Pass exception on to the program being debugged?": choose Yes.
- File - Open and open one or more source files from the additional DLLs you specified in "Set up" above.
- Set breakpoints in these files, as needed.
- Bring up a suitable form in a Web browser or somehow cause your AppLogic to execute, and debug normally.
Previous Contents Index Next
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.
Last Updated November 25, 2002