A "Rich" Alternative for System i GUI Development
The prior blog entry presented a Java console application which performs the same function as the CL view-controller -- write a data queue then read. The examples used the techniques covered in IBM's documentation. That was a starting place -- putting the classes explained in the Java toolbox documentation into a console view-controller.
The write-then-read pattern does not work for GUI clients. The desktop application has to be free to service inputs from the user while waiting for the data queue read to happen. The program can't be locked waiting for model output on the data queue.
The Java console application of the last entry is re-written to place the data queue read portion of the write then read pattern in a separately running thread. The main program spawns a thread which waits for the model output data queue and reads it. After the thread is spawned the main program is free to do whatever … in this case wait for input from the user and write to the model input data queue.
I haven't found examples of using JTOpen Java toolbox data queue classes in threads. Over the years I have developed several techniques of running data queue classes in threads.
dataqueues.DtaQExample3Thread.java is a class that reads the model (or server) output data queue. When a data queue entry is read the class passes the Record object read to be processed. In this case the Record object, that represents the model output data structure, is turns it into Java variables (String objects) and written to the console.
The operation of this class is narrowly defined:
- wait for data on the model output data queue
- when the data is read package it into a Record object
- fire a PropertyChange event which contains the Record object which was just read and wait for the next data queue entry
- handle any exceptions
- when told to clean up and end the thread
My experience is that the thread which reads a data queue should do as little as possible but do it well. Most of its time is spent waiting on a data queue.
Important points in this class are
a) the AS400 object is instantiated and passed to the thread object when it is created by the constructor
b) the class handles its data queue exceptions
c) the class cleans up after itself and shuts the thread down (thus shutting itself down)
d) the java bean PropertyChange classes are used by the thread to communicate
a) The AS400 object is a shared resource, shared by all the parts of the Java application running in one instance of the JVM. It is created and managed outside the thread. The thread merely uses it and handles any exceptions which result from the threads use of the AS400 object. That is why it is passed to the thread in the constructor.
The AS400 object will used for other services between the Java client and the System i server. Reading the model output data queue is just one use. For this example the AS400 object will also be used to write the input received through the console to the model's input data queues. In a real MVC scenario the AS400 object would also be used by message queues and perhaps JDBC or record access services.
b) The thread waits to read the data queue. What if something goes wrong? The thread has to handle the error or at least pass it back to the program. My experience is that it is best if the thread handles the errors. Most of the errors are extremely fatal. To keep this simple I just dump the stack trace and crash (System.exit(0)).
c) The thread spends most of its time waiting for a data queue entry. It can't do anything else while it is waiting. How do you tell the thread to stop waiting and do something else?
In this example I took the cheap way. One thing that the thread will notice while it is waiting for a data queue read is if the data queue goes away! The thread specifically traps for the condition that the data queue went away. When that happens the thread cleans up and terminates its self. The caller ends the data queue services, gives the thread a few moments to notice and end itself, then goes about its business.
I have used two other methods, both more sophisticated than pulling the rug out from under the data queue thread.
1) Send the thread a message to shut down through the data queue it is reading. Remember, the thread is reading a data queue. It doesn't know where the message originated. If the thread processes a "terminate" message then either the main Java application or the System i server can send this message. In the case of a Java rich client the main Java application would send the message to "terminate" during the shut down process. In a more traditional client server program the server might send the terminate message and the thread pass the information to the main program, perhaps shutting it down.
2) Instead of waiting forever for the data queue read waits a short period of time. When the read times out the program looks to see if it should continue reading the data queue. I use this in conjunction with a shutdown() method in the thread.
- The main program call DtaQThread.shutdown().
- shutdown() sets a shutdown flag in the thread
- the next time the read times out the program sees that shutdown flag is set and acts. Otherwise it goes into another read cycle.
Waiting forever on a data queue read has subtle problems for long running client server programs. Basically the code reading the data queue will never get data, or see that there is a problem, if the data queue goes away. Seriously, the JTOpen toolkit read data queue class won't notice that the System i has been IPLed if the data queue read timeout is a -1 (forever). If the data queue read times out and then read again for N seconds it will see that something happened to the data queue (like it is no longer there or was recreated) and can handle the error.
For simplicity sake in this example I took the easy way out. When the main program is stopped by the user typing *STOPITNOW the data queue service is disconnected. The thread will take that error as a signal to clean up and die.
d) Data is read from the model output data queue. Now what? How is that communicated to the main program? For this example I chose java been PropertyChange classes but there are several ways it could have been done.
I don't use the DataQueueListeners which can be attached to a DataQueue object because they don't work well to my mind. If you want to discuss it leave a comment.
The Java bean PropertyChange classes are a good choice. The thread can read the data, do whatever processing it needs to do, and fire a PropertyChangeEvent that contains the data read from the data queue. The code controls the point the change event is fired and what is communicated to the listeners.
The PropertyChangeListener "hears" the fired event and acts on the data. In this case the PropertyChangeListener unravels the Record object from the data queue read and writes it to the console.
There are several other ways to do this. I have tried a few of them. Please leave a comment if you have another way to do it.
Also note that a GUI client is a multi-threaded program by nature and may already provide a means for the thread to notify the rest of the client that a data queue entry has been read. Remember, the purpose of this example is to give an alternative example of data queue use for a rich client. This is just a starting point, something simple to explore and experiment with.
Enough for now -- perhaps too much, certainly not enough.
The other parts of this example, Example3, will be addressed in the next blog entry. There are three version of Example3, all use the same DtaQExample3Thread class. Here is the code for the rest of the example if you want to try DtaQExample3Thread.
DtaQExample3a implements PropertyChangeListener as a separate class.
DtaQExample3b implements PropertyChangeListener as an anonymous inner class.
DtaQExample3c implements PropertyChangeListener in its declaration and provides the methods of PropertyChangeListener
Enjoy!
Posted by Bill Blalock at April 8, 2007 8:00 PM

| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Our blogs are editorial content of System iNetwork. We welcome your comments and opinions and encourage lively debate on the issues, and we reserve the right to edit all postings for clarity, length, civility of tone, and appropriateness to the topic under discussion. Comments consisting of product or job solicitations and other spam, profanity, and extreme rudeness will be deleted. We also reserve the right to publish excerpts from the blogs in our e-mail newsletters and print magazine.