Imagine being able to finish a work task during the commute to work--all on a device small enough to fit in your pocket and go with you anywhere.
The ability to work from home has increasingly become a reality, and it is beginning to change the landscape of the workplace. The newest trend is not a replacement for the current "at home" model, but an augmentation to it. This trend involves being able to work from anywhere. And this new trend of being connected doesn't just involve work; it involves all aspects of life. Accessing data and staying connected can impact almost everything we do.
Tier 0 Devices
The devices that are going to allow this new trend to come to pass are called tier 0 devices, and their sales are growing. An extension of the "old" three-tier computing model (the mainframe at tier 3, the application or Web server at tier 2, and the client desktop or laptop at tier 1), tier 0 refers to the next level down. Tier 0 devices are predominantly thought of as Web-enabled cell phones and personal digital assistants (PDAs). What all tier 0 devices all have in common is that they are relatively small and often cheap enough to embed in practically anything. The ability to network the devices together is what will make these devices even more powerful.
Large companies are looking to mobilize their employees and free them from tedious tasks such as completing multiple copies of paper work or filling in computer entry screens. A tier 0 device in the hand of a worker on the factory floor, a real estate agent showing and bidding on homes, an insurance agent at the site of a disaster, or a salesman at the customer's office can enable that freedom.
In this article, we'll outline a new technology called ToolboxME. We'll introduce you to the ability to access iSeries commands, programs, and databases from anywhere.
ToolboxME stands for "IBM Toolbox for Java Micro Edition." The primary goal of ToolboxME is to allow access to iSeries data from a tier 0 device, but it can be much more than that.
Data Access from Anywhere
Our first task in accomplishing the goal of instant access to data was to investigate some of the things that were currently going on in the industry. When we did this, we found that the vast majority of companies were focusing on synchronizing data on tier 0 devices instead of accessing live databases.
In a data synchronization model, each user's tier 0 device has a copy of pertinent data from the database. Periodically, the data on each device is synchronized between the device and the database. The synchronization model works fairly well for data that is not very dynamic or for data that is not modified or summarized by large numbers of people.
The data synchronization model starts to fall apart as the data becomes more dynamic. For example, if you have an auction application and you place a bid on a product, you don't want to wait until you are at home that evening to find out whether or not you have the highest bid. You need to know immediately.
Conflicts can also arise if you try to do any form of scheduling. You probably want to know right away that the 1:00 p.m. Tuesday meeting you are trying to set up will overlap with the Board of Directors meeting so you can take immediate action on the conflict.
Finally, some users need to see summarized data on the fly. For example, during the course of the day, decisions might need to be made that require having up-to-the-minute information. If you have to wait until morning to access the new synchronized data, it may be too late.
Another problem with synchronous data is that it requires additional servers and software configuration complexity to accomplish the task. You have to have software and systems (synchronization servers) in place to handle conflict resolutions--or you may even have to resolve conflicts manually. These ideas may cause concern when you think about the concept of thousands or hundreds of thousands of connected devices.
Wireless Environment
As with any other Java-enabled environment, you'll need a virtual machine to execute a Java program. All wireless devices use the Connected Limited Device Configuration (CLDC), which is the specification outlining J2ME (Java2 Micro Edition) features in wireless devices. Built on top of the CLDC specification is the actual virtual machine. The KVM (K Virtual Machine) and Mobile Information Device Profile (MIDP) are two Java virtual machines that are available today.
The "K" in KVM stands for "kilo" because its memory budget is measured in kilobytes (whereas desktop systems are measured in megabytes). The KVM was the original JVM for wireless devices, but the new standard is the MIDP.
A "profile" is a collection of Java-based APIs that supplement a configuration to provide capabilities for a specific device type. While the CLDC provides the basic Java classes like java.io, java.util, and java.lang, a profile provides additional packages, such as javax.microedition.lcdui, to supplement the base packages.
The application developer will probably find that GUI development for the tier 0 device is problematic in the Java specifications. GUI development differs for various JVM implementations, and the CLDC specification doesn't explicitly talk about what an appropriate GUI component set should be for the tier 0 device.
One option is to use the kAWT toolkit as a mechanism to get up to speed on these devices very quickly. The kAWT toolkit will let you use normal AWT GUI development, so you can focus as little as possible on the GUI and as much as possible on your application. A second option is to use the MIDP, which provides its own GUI classes that are different from those provided by the kAWT.
The ToolboxME Basics
What you really want is for everything on your tier 0 device to work exactly like it would if you were sitting at a system in your office. Your application should be able to use all of the same resources provided by the database (stored procedure business logic and data) that you would while in the office. Although some necessary limits are imposed by size requirements, ToolboxME comes much closer to this goal than other data-synchronization-based solutions.
ToolboxME focuses on iSeries access to commands, programs, data queues, and databases. It currently supports any tier 0 device that has a JVM, and it has been tested on both PDAs and cell phone emulators. The functions provided are based on the existing IBM Toolbox for Java.
Of course, the conflicting goals of being extremely small and still highly functional had to be addressed. The list of APIs provided by the Toolbox for Java is very large. Today's popular tier 0 devices are very constrained. In order to make a logical fit, we needed to trim away many of the things in our the Toolbox API set. For example, the JDBC DatabaseMetaData interface alone has about 150 methods. We chose to not support it at all. We chose to support very few of the ResultSet getXxx methods, and we chose not to support any of the CallableStatement interface methods at this time. With the exception of the AS400 object, static methods are used to perform a request to minimize the number of objects being used by the application.
Technical Introduction
So with so much function missing or changed, what can you do and how do you do it?
MEServer
All client requests are sent to the MEServer, which is a Java program that can be running on any machine with a compatible virtual machine. That means it can be running on a PC, a Linux box, or even the iSeries. The MEServer receives the client requests and performs them using the full IBM Toolbox for Java APIs on behalf of the client to the specified iSeries and then returns the requested data to the calling client. Figure 1 shows an example.
Figure 1: The MEServer sits between the client and the iSeries to provide real-time data.
By default, the MEServer uses port 3470, but you can configure it to use another port. The AS400 object would then specify the name of the machine the MEServer is running on along with the configured port number if it is anything other than the default value. Figures 2 and 3 show some examples.
Start the server from a command line as follows:
Figure 2: The MEServer can be run on any machine with a Java Virtual Machine (JVM), including a PC via a command line.
Figure 3: The MEServer can also be run on the iSeries in QSH or via the RUNJVA command.
AS400 Object
The AS400 object is the base for all other ToolboxME functions. It represents a connection to the iSeries from a wireless device. An application can use the AS400 object to connect and disconnect from the server.
The one difference between the ToolboxME version of the AS400 object and the normal Toolbox AS400 object is that ToolboxME requires you to specify one additional parameter on the constructor. The additional parameter is the name of the system that is running the MEServer. This will allow the wireless client to communicate with the MEServer so that the MEServer can perform the request and return the data. Figure 4 shows an example.
The following example demonstrates the use of AS400:
try
{
system.connect();
}
catch (Exception e)
{
// Handle the exception
}
// Done with the system object.
system.disconnect();
Figure 4: This shows a sample SignOn application running on a Palm device.
CommandCall
This class allows the user to call an iSeries server CL command from a wireless device. The main difference is that you will call the run() method statically. There is no need to create a CommandCall object. Doing so would only increase the size of the virtual machine.
Passing in an AS400 object and the name of the command will run that command on the iSeries and return an array of messages. The length of the string array returned will be zero if there were no messages. Also, if connect() has not already been called on the AS400 object, a connection will be made implicitly when running the command. Figures 5 and 6 show some examples.
The following example demonstrates the use of CommandCall:
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
try
{
// Run the command "CRTLIB FRED."
String[] messages = CommandCall.run(system, "CRTLIB FRED");
// Display any messages returned.
for (int i = 0; i < messages.length; ++i)
{
System.out.println(messages[i]);
}
}
catch (Exception e)
{
// Handle the exception
}
// Done with the system object.
system.disconnect();
Figure 5: This is a sample CommandCall being run from a Palm device.
Figure 6: Here's the same CommandCall being run from a cell phone.
ProgramCall
The ProgramCall class allows a user to call an iSeries program and access data returned after the program runs from a wireless device. Instead of adding the overhead of using ProgramParameters, PCML is being used to call a program. The advantage of this is that the client only needs to pass the MEServer the name of the PCML file, the API being called, along with the parameters to set and get. All of the loading and parsing of the PCML is done by the MEServer.
Each PCML document must be registered with the MEServer. The document can be registered during runtime when the PCML document name parameter is provided or as an argument when the MEServer is started.
The registration is simply telling the server which PCML-defined program(s) to run.
A hashtable is used to specify the names and values of the parameters to set. The key in the hashtable is the name of the parameter to set, and the key value is the value of the corresponding parameter to set. There is also a string array that specifies the name of the PCML output parameter(s) to return. Figure 7 shows an example.
The following example demonstrates the use of ProgramCall:
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
// See the PCML example in the Toolbox programmer's guide.
String pcmlName = "qsyrusri.pcml"; // The PCML document describing the
program we want to use.
String apiName = "qsyrusri";
// Parameters that we need to set when calling the API.
Hashtable parametersToSet = new Hashtable();
parametersToSet.put("qsyrusri.receiverLength", "2048");
parametersToSet.put("qsyrusri.profileName", "JOHNDOE" };
// These are the values that we've chosen to retrieve.
String[] parametersToGet = { "qsyrusri.receiver.userProfile",
"qsyrusri.receiver.previousSignonDate",
"qsyrusri.receiver.previousSignonTime",
"qsyrusri.receiver.displaySignonInfo" };
String[] valuesToGet = null;
try
{
valuesToGet = ProgramCall.run(system, pcmlName, apiName,
parametersToSet, parametersToGet);
// Get and display the user profile.
System.out.println("User profile: " + valuesToGet[0]);
// Get and display the date in a readable format.
char[] c = valuesToGet[1].toCharArray();
System.out.println("Last Signon Date: " +
c[3]+c[4]+"/"+c[5]+c[6]+"/"+c[1]+c[2] );
// Get and display the time in a readable format.
char[] d = valuesToGet[2].toCharArray();
System.out.println("Last Signon Time: " + d[0]+d[1]+":"+d[2]+d[3]);
// Get and display the signon info.
System.out.println("Signon Info: " + valuesToGet[3] );
}
catch (MEException te)
{
// Handle the exception.
}
catch (IOException ioe)
{
// Handle the exception
}
// Done with the system object.
system.disconnect();
Figure 7: This is a sample ProgramCall being run from a Palm device.
DataQueue
The DataQueue class allows an application to access iSeries data queue objects. Similar to the other functions available in the ToolboxME, no object is ever created. The methods provided to read and write string or byte data are static. Figure 8 shows an example.
The following example demonstrates the use of DataQueue:
try
{
// Write to the Data Queue.
DataQueue.write(system, "/QSYS.LIB/FRED.LIB/MYDTAQ.DTAQ", "some text");
// Read from the Data Queue.
String txt = DataQueue.read(system, "/QSYS.LIB/FRED.LIB/MYDTAQ.DTAQ");
}
catch (Exception e)
{
// Handle the exception
}
// Done with the system object.
system.disconnect();
Figure 8: This is a sample Data Queue being accessed from a Palm device.
JdbcMe
There is support for ResultSets that are both scrollable and updateable. There is support for using all of the transaction isolation levels. There is also support for PreparedStatements and stored procedure calls as long as the stored procedure doesn't try to return output parameters. All of the underlying features of the database are still used such as triggers and user-defined functions. Today, all of this functionality is available in a JDBC driver that weighs in at about 40K on the device itself.
As with any JDBC driver, creating a JdbcMe connection requires unique values in the URL:
There are only a couple of JdbcMe specific details to note. First, the URL specified is a normal JDBC URL that is ultimately passed directly to whichever JDBC driver is configured on the JdbcMe server that processes the SQL request. In this example, "jdbc:as400://system" is an IBM Toolbox for Java JDBC URL.
There is one piece of information that is very specific to JdbcMe in the URL. The JDBC property "meserver" is set to indicate where the Toolbox MEServer is running (the default port of 3470 doesn't need to be specified).
After the JdbcMe connection is made, all subsequent JDBC operations act exactly as a JDBC programmer would expect. Be aware, though, that in order to keep the size and complexity of JdbcMe to a minimum, many JDBC classes and methods have been removed.
Since a major focus of JdbcMe was stripping the standard JDBC specification to the smallest, most useful subset of functions, it's important to talk specifically about the things that are present in the JdbcMe driver.
You can use JdbcMe to insert or update data on your iSeries the same way you would use JDBC on any other platform: Statement.execute(), Statement.executeQuery(), and Statement.executeUpdate(). JdbcMe also provides the advanced JDBC 2.0 features of scrollable and updateable result sets as long as the JDBC driver you've configured in the database server supports those features: ResultSet.TYPE_SCROLL_SENSITIVE and ResultSet.CONCUR_UPDATEABLE .
You can also access the more advanced features of your database using the standard JDBC logic. You can control transactions (Connections.commit() and Connection.rollback()), and you can modify transaction isolation levels if fine-grain control on concurrency issues becomes important to your application (Connection.setTransactionIsolation()).
SQL work done by JdbcMe can include calls to stored procedures or drive triggers that are written in any language. Stored procedures and triggers allow your PalmPilot or cell phone device to tie into your existing applications with a minimum change. Note: The JDBC classes PreparedStatement and CallableStatement are not currently provided, so these features are accessed through normal Statement objects.
Since adding many supported data types would increase the size of the JdbcMe driver, your application, and even your virtual machine, JdbcMe allows you to access all SQL data types as Java String values.
JdbcMe also provides several other basic features that will aid in your application development.
JdbcMe is unique in that it can easily function as a "universal JDBC driver." An application using it can target any backend database without requiring it to load other drivers or change configuration. Indeed, a single application can even target two heterogeneous databases at the same time, using the same driver with only a simple URL change. No additional configuration (driver code loading or distribution) is required for the client to access additional heterogeneous clients.
JdbcMe also provides a standard mechanism for persisting data to offline storage. In a typical application intended for tier 0 devices, there are two categories of data. The first category of data is "offline data." Offline data is accessed very frequently for display purposes, and it changes infrequently. The other category of data is called "live data." Live data changes frequently, and it is typically accessed in a transactional fashion. When accessing live data, it is much more important to get the correct data values.
In a real estate application, the offline data is the description of real estate property. The live data would be a calendar reflecting schedules for agents showing the property and any current bids that have been submitted on the property.
In a product catalog application, the offline data may be product listings, features, and SKU numbers. The live data in the same application would likely be current price, quantity on hand, and discount availability.
JdbcMe provides a simple mechanism for storing the results of a live query in an offline data repository: Statement.executeToOfflineData(). The data can later be accessed and updated without making a JdbcMe connection, but by still using normal JDBC query results processing (creating a ResultSet of the JdbcMeOfflineResultSet type).
The following JdbcMe code stores the results from a query in a device-specific way to an offline data store on the device that is running the JdbcMe application. The name, creator, and type parameters of the executeToOfflineData() function are used to uniquely identify the offline data store depending on the device that the JdbcMe application is running on. For a PalmPilot device, the creator and type identify the offline data while the name is simply retained. For a cell phone device, the name uniquely identifies the offline data while the creator and type are ignored.
((JdbcMeStatement) stmtOjbect).executeToOfflineData("select * from
qcustcdt.qiws", "TestQueryResults", dbCreatorName, dbType);
The following JdbcMe code creates a ResultSet over data that was previously stored offline on the device. The ResultSet functions as a normal JDBC ResultSet and can be used to update the offline data. Figure 9 shows an example.
ResultSet rs = new JdbcMeOfflineResultSet("TestQueryResults", dbCreatorName,
dbType);
// Process the result set normally as a scrollable, updateable result set.
while (rs.next())
{
String s = rs.getString(1);
}
Figure 9: Use JdbcMe to access iSeries data from a Palm device.
Availability
The IBM Toolbox for Java 2 Micro Edition (jt400Micro.jar) is available as part of JTOpen, which is the open-source version of the IBM Toolbox for Java and the V5R2 iSeries Access for Wireless LPP. The jt400Micro.jar contains all of the necessary client code to write an application for a wireless device. The MEServer portion is part of both JTOpen and V5R2 IBM Toolbox for Java LPP and is packaged inside jt400.jar.
As of V5R2, this will be available as part of Toolbox LPP and in Version 3.0 of JTOpen. JTOpen 3.0 is already downloadable as source and binaries.
Have ToolboxME, Will Travel
We've mentioned some of the user scenarios that demand data access on tier 0 devices. We've briefly touched on the design rationale and introduced you to the technical aspects of application development using ToolboxME.
You now have everything it takes to begin making some amazingly cool and useful iSeries applications that can travel anywhere you do. The tier 0 environment still has much room for invention and discovery. Hopefully, these devices and ToolboxME will make your job easier, but more importantly, much more fun.
Fred Kulack has worked at IBM since 1994. Focusing on eServer iSeries application portability, he has designed and implemented operating system APIs and runtime for the Unix-type and Pthreads APIs. Joining the DB2 UDB for iSeries team in 1998, Fred focused on Java data access, including design and implementation of the DB2 UDB for iSeries JTA enhancements to the iSeries transaction model.
LATEST COMMENTS
MC Press Online