What’s the benefit of using Java if it means rewriting all of your legacy systems? Well, you don’t have to rewrite everything! Here’s a step-by-step road map that shows you how to create a Java user interface that talks to your legacy business rules.
All right, I’ll admit it. This article came about as an answer to the current wisdom that Java can’t do business applications. Yes indeed, I’ve heard those words so many times now that they’re getting under my skin just a little bit. Yup. I’ve talked myself blue in the face trying to answer the naysayers, but it finally became obvious to me that I had to put my money where my mouth is.
Well, folks, I’m here to say that Java does business. However, I need to clarify that a bit. I’m not saying you should use Java and object-oriented programming (OOP) for everything and throw away all that you’ve ever learned about RPG (or COBOL, for that matter) and business applications. In my opinion, Java isn’t at that point yet, (it’s coming, though) and neither is object technology. Instead, Java provides us with the impetus to finally create those client/server applications we’ve talked about for so many years. Let me show you how.
The Client/Server Paradigm
In true client/server architecture, a client controls the user interface and sends requests to a server to perform all database functions. You can use many other models, but none of them is the focus of this article, and hopefully I can explain why I believe client/server to be so important.
With client/server, the client is free to request whatever data it chooses from the server, meaning that while we’re converting our legacy systems, we’re also providing servers for brand-new, previously unthought of applications. Servers are essentially software components that provide relevant data on request without the client application’s having knowledge of the actual database. (Note that this is also the first step toward object technology, freeing the client application programmer from the business rules.)
In most other distributed models, the user is trapped into whatever business flow the host programmer decides is important, and the user interface is a strict replica of the old green-screen approach. In a client/server model, however, there is much more flexibility. A
client programmer can use all the tools available to her on the workstation: For example, she can easily program the ability to drag-and-drop a customer number onto a form, which will trigger the addition of the customer’s mailing address. This sort of freedom simply isn’t available with the generic “facelift” architectures.
Why WORA?
Write Once, Run Anywhere (WORA) is the carrot that can justify the effort of reengineering for client/server. When I first designed client/server applications back in the early 90s, the only operating system that was robust enough for such use was OS/2. Unfortunately, after we made the decision to develop for OS/2, we were locked into that platform. As OS/2’s fortunes dwindled, so did those of some wonderful graphical products. And that signaled the end of our client/server strategy for many years. It’s really too bad, now that I look back on it, because had the company continued to develop along those lines, it would have been poised to take over the world with the advent of Java.
You see, with Java, I no longer have to worry about my target platform. If I stick with the core classes, such as Swing (also known as the Java Foundation Classes, or JFC), I know that my clients will run on any platform, anywhere—OS/2, Windows, Mac OS, UNIX, Linux, it doesn’t matter. Java is becoming ubiquitous; someday, I’ll be able to run my applications on my toaster.
What About the Server?
Ah, herein lies the rub, and much of the confusion about Java. Somehow, the goal has become to quickly rewrite all of your legacy code to Java, but that simply isn’t necessary or even advisable in most cases. In our particular niche, that of the AS/400, server-side Java simply isn’t ready for prime time, and the other option of transferring all of the business logic to the workstation is a poor design choice. One simple reason is that, by keeping all the business rules on the server, you don’t have to worry about distribution issues. If the business logic is on the workstation, business logic changes must be distributed to every client in the network. Distribution of upgrades never happens uniformly, which leads to having outmoded business logic on some of your clients. Therefore, the business logic should remain on the server, and for now, at least, traditional programming languages, such as RPG, are the best tools for server-side development.
My personal choice is to design client applications written in Java on the workstation that communicate with servers written in RPG on the AS/400, using data queues to pass messages back and forth. I use IBM’s AS/400 Toolbox for Java for the necessary classes to connect to the AS/400, to call my message APIs, and to convert between AS/400 data types and Java data types. That said, now it’s time to try your hand at designing a Java user interface that means business. What’s Really in an Interface?
In a 24 x 80 green-screen business environment, there are really only a few basic interface types. For the most part, you have single-panel, multiple-panel, and subfile inquiry and entry. Anything else is a combination of these basic types. (The difference between single- and multiple-panel entry is that fields from one panel need to be validated in conjunction with fields from another; the difference between single- and multiple-panel inquiry is semantic.)
My example is going to take one of the simpler interface types, but one that demonstrates most of the issues involved in interface design: the single-panel entry interface. In its simplest form, this interface consists of the following components:
• Output Fields. These can include things like company name, user ID, date and time, and so forth. The user never modifies them.
• Entry Fields. These are the standard data fields. They include numeric and alphanumeric fields.
• Function Keys. This is usually how the user indicates what to do next.
• Error Messages. Sometimes overlooked, error messages are essential to a business application.
Because of space limitations, I’ve deliberately left out a few things, such as help text and support for double-byte character sets. These issues are important, but they can be dealt with at another time.
How Do I Implement These in Java?
Standard components in the JFC can be used to mimic the AS/400 screen features. For example, a text field is the equivalent of an input-capable field on the AS/400, while a label can be used in place of an output-only field. Buttons generally replace function keys. The furthest stretch is the message subfile on the AS/400, but it can be adequately replaced by a drop-down list.
I’ve created an application called ItemMaintainer that acts as the client for item master maintenance. For comparisons, please refer to the article “Breaking Apart the Monolith,” elsewhere in this issue. The ItemMaintainer client communicates with the RPG server designed in that article. The first four figures in this article are ItemMaintainer’s GUI replacements for the first four figures in that article.
Figure 1 shows the front-end program, which prompts for an item number; I select the operation to perform by pressing the appropriate button. If I press View, I get a View panel, as shown in Figure 2. If I press Revise instead, I get the Revise panel in Figure 3. Notice that in Modify mode, the non-key screen fields are now unprotected, so I can change them. At this point, I can hit Edit to simply edit my changes or Accept to accept them and try to post them (assuming there are no errors). If there are errors, a screen like Figure 4 is displayed, with the prompts for the invalid fields in red and a drop-down list with all the error messages. At any point, I can simply close the window to cancel (not undo!) any changes.
One key difference between the Java client and the AS/400 client is that on the workstation, the user can have multiple maintenance windows running all at the same time, something all but impossible on the AS/400. As I noted earlier, a good programmer will allow drag-and-drop between fields; think how beneficial that capability would be when trying to copy a few key fields from one item or one customer to another.
Great! Where’s the DDS for These Screens?
Java doesn’t really have a DDS. You can get an Integrated Development Environment (IDE) that helps you create forms, but I am highly averse to those for reasons outside the scope of this article. And to be honest, it’s not that difficult to put together a Java panel from scratch, especially if you have some base classes to work with.
If you have a strong PC background, you may have noticed some things about the panel that aren’t exactly standard. For example, my protected fields have a black background, and the text for the prompts turns red for fields that are in error. These are features of a base class I’ve developed called EntryField. (The source for this and the other Java classes and RPG programs used in this article are available on the Web at www.midrangecomputing.com/mc/99/05.) If you don’t like my conventions, you can make your own by modifying or extending my class; if you do like them, you can use them as they exist. I’ve also created two other classes, VerticalEntryFieldPanel and ButtonPanel. These classes make it pretty simple for me to throw together a single-panel entry screen. About 230 lines of code in total, these classes can be used by any program that needs a standard look for its entry panels.
The other utility class used in this application is the DqmSession class, which provides all the support needed to communicate with the AS/400. It’s another 158 lines, but like the interface classes mentioned in the previous paragraph, the DqmSession doesn’t need to be modified to be used in another application.
Together, these base classes provide the underlying support for the classes that actually make up the ItemMaintainer application, much in the same way RPG and DDS provide built-in support for database access and screen I/O, respectively.
What’s in a Java Client?
On the AS/400, the program ITMSEL displays the item number prompt, then calls ITMCLT with the item number and the appropriate operation code (add, modify, copy,
delete, or view). ITMCLT displays the item entry panel, sending requests to ITMSRV for database access. The idea is similar on the workstation, although encapsulated in classes. These application classes require a little more than 350 lines of Java.
The ItemMaintainer class is a very simple application class. It displays a panel with one entry field and five buttons (add, revise, copy, delete, and view). Rather than testing to see which function key has been pressed (as you would in an RPG program), in Java, each button has a listener assigned to it that is invoked when the button is pressed. Each of the buttons in ItemMaintainer has a listener that creates a new instance of ItemPanel and then executes the appropriate method, passing the item number if appropriate. (The fact that each listener creates a new instance of ItemPanel is what allows ItemMaintainer to launch many item maintenance panels concurrently.) Figure 5 shows the code for ItemMaintainer in its entirety.
ItemPanel is the equivalent of ITMSRV on the AS/400. (Figure 6 shows the code snippet that creates ItemPanel’s user interface; observe how easy it is to configure a completely different interface using the same utility classes as ItemMaintainer.) The view() method simply gets the item and shows it to the user, hiding the buttons. The user can exit only by closing the window. The other methods get the selected item and move its data to the entry fields—except for add(), which clears all the fields—protecting whichever fields need to be protected. Then, they show the panel. In addition, they set the request op code for the Edit and Accept buttons. Add() and copy() set the op code to WRITE, revise sets it to UPDATE, and delete sets it to DELETE. When one of these buttons is pressed, the appropriate request is sent to the server by a call to the Item class. Upon return, any errors are displayed, and the corresponding fields are highlighted.
The Item class is the final piece of the client. It is basically a surrogate for the ITMSRV server on the AS/400. The ItemPanel class makes a request, which is forwarded via a call to DqmCSnd, and the responses are retrieved via DqmCRcv. Item is responsible for converting the AS/400 data types for the item record to Java data types and back, but that’s pretty much all it does.
A Side Benefit
An often overlooked side benefit of moving to client/server technology is the immediate in savings hardware costs. By moving your green-screen 5250 applications to Java clients, you reduce your interactive load on the AS/400, thereby allowing you to choose a less-expensive server model. Now, you have inexpensive workstations talking to a less-expensive server and still have the same great performance. Yet another benefit of the client/server architecture is that you can deploy green-screen clients beside workstation clients using the same servers, phasing out your dumb terminals as you see fit rather than forcing an en masse cut-over.
A Good Start
Although not the quick fix of a facelift-server/client approach, true client/server technology can produce immediate benefits by reducing interactive workload without any mass disruptions of either hardware or software. And, unlike the server/client route, this is not an architectural dead end but rather the first step in an evolutionary road to object technology.
And while we can agree that the ideal of distributed object processing has long been one of the ultimate goals of computing, the worry has always been that it’s too dangerous and expensive a destination. Well, it’s finally a journey you can afford to begin today. In fact, it may well be a journey you can’t afford not to take.
Figure 1: The item select program allows the user to enter an item number and select the action to perform.
Figure 2: In View mode, all entry fields are protected.
Figure 3: In Revise mode, only the key fields are protected.
Figure 4: If errors are encountered, the invalid fields are highlighted and the messages are displayed in a drop-down list.
public class ItemMaintainer {
// Put these variables here so my button handlers can see them
private EntryField[] fields;
// Open a session with the AS/400: it has to be final because
// the window listener can't handle non-final objects.
private final DqmSession session = new DqmSession("your domain");
public ItemMaintainer() {
// Create Window
JFrame frame = new JFrame("Item Panel");
// Create field panel (with one field, Item Number)
fields = new EntryField[] { new EntryField("Item Number:") };
VerticalEntryFieldPanel fieldPanel =
new VerticalEntryFieldPanel(fields);
// Create buttons and attach listeners to them
String buttons[] = new String[]
{"Add", "Revise", "Copy", "Delete", "View" };
ActionListener listeners[] = new ActionListener[]
{ new AddItem(), new ReviseItem(), new CopyItem(),
new DeleteItem(), new ViewItem() };
ButtonPanel buttonPanel = new ButtonPanel(buttons, listeners);
// Add fields and buttons to window
frame.getContentPane().add(fieldPanel,"West");
frame.getContentPane().add(buttonPanel, "South");
// Size the window
frame.setSize(new Dimension(400, 125));
// Center the window
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height)
frameSize.height = screenSize.height;
if (frameSize.width > screenSize.width)
frameSize.width = screenSize.width;
frame.setLocation((screenSize.width - frameSize.width) / 2, 0);
// Shut down the session and end the program when the window closes
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
session.exit();
System.exit(0);
}
});
// Show the window
frame.setVisible(true);
}
// This runs the application as a command line application
LATEST COMMENTS
MC Press Online