Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
RPG To Desktop
By Aaron Bartell
aaronbartell@mowyourlawn.com
Copyright ©2008, Aaron Bartell
Abstract
Every so often, I see the mailing lists address the topic of how to
automatically open desktop applications from RPG when the
user presses a key in a 5250 session. Usually, the need is to
open a browser window and deep link into a Web site by
passing a long URL string (e.g., http://ups.com/trackpackage?
packageid=Z123412341234). The standard answer is to use
one of the features in Client Access (i.e., STRPCO or
STRPCCMD). While that works in some cases, an alternative
approach is to spin your own wool. That's where I come in.
This session provides instructions (and actual code) for
integrating your RPG programs with the desktop by using a
relatively small amount of Java.
MowYourLawn.com
• Inception: 2002-11-03
• Free and Open SourceTools
– RPGMail
• 3352 downloads (since 2006-06-01)
– RPG Chart Engine
• 1248 downloads (since 2006-10-10)
– RPG To Desktop
• 768 downloads (since 2007-11-07)
– System i SVN Client (source control)
• 342 downloads (since 2008-02-21)
What and Why
What: A way to send commands from the IBM i to the
PC to bridge the gap of communication. Not only
that, but it forges a path for other types of
applications (i.e. thin Java client to render screens).
Why: Had a customer with a similar need. They didn't
want to rely on IBM's Client Access. The other
obvious reason is because if I didn't let it out, my
head would explode. I chose the lesser of two evils
<grin>.
Java is an EXCELLENT technology when used around
the edges to compliment the IBM i and RPG!!
RPG To Desktop Uses
1. Open browser on PC with unlimited URL length.
2. Open image viewing software on PC (fax images anyone?).
3. Click on customer in 5250 and open browser to Salesforce.com
4. Open email client with pre-filled to/from addresses, subject, and body.
5. Launch ANY Windows application!
6. Open ANY Windows file!
7. Play REALLY mean jokes on a coworker by installing it on their PC and
then randomly invoke different commands
from your 5250 session. YOU DIDN'T
HEAR THIS SUGGESTION FROM ME!
Though if you get them on tape please
send it to me:-)
Requirements
At least OS/400 V5R1, though it could work on a
lesser OS version through some easy RPG code
changes. I only have access to a minimum of
V5R1 and who wants to code RPG on a release
before they had /free form! <grin>
RPG Compiler (to recompile example programs with
your info)
Java 1.5 loaded on users PC.
One Furry Java Llama... You are, after all, using Java!
Installation
1. Download the zip file from the following location and unzip it to your desktop.
http://mowyourlawn.com/RPGToDesktop.html
2. Issue the AS/400 command:
CRTSAVF FILE(QGPL/RPG2DT)
3. FTP file RPG2DT.savf from your PC to the AS/400 using BINARY mode
into save file QGPL/RPG2DT.
4. Issue the AS/400 command:
RSTLIB SAVLIB(RPG2DT) DEV(*SAVF) SAVF(QGPL/RPG2DT)
5. Right click on the Start_RPGToDesktop.bat file and select Edit.
Modify the contents to have values appropriate to your
environment (i.e. modify the ip address, user and password fields).
6. Double click on the Start_RPGToDesktop.bat file.
7. Issue the following command from the command line. Make sure
library RPG2DT is in your library list. Your browser should open
to the website http://mowyourlawn.com.
RPG2DT UNQKEY(00001) DQLIB(RPG2DT) DQNAM(DQRPG2DT)
PCCMD('rundll32 url.dll,FileProtocolHandler http://mowyourlawn.com')
JT400.jar – what is it?
Included with the RPGToDesktop download is file JT400.jar with an official name of
“IBM Toolbox for Java”.
Official website: http://www-03.ibm.com/systems/i/software/toolbox
Open source version: http://jt400.sourceforge.net
Things you can do utilizing the IBM Toolbox for Java:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Database -- JDBC (SQL) and record-level access (DDM)
Integrated File System
Program calls
Commands
Data queues
Data areas
Print/spool resources
Product and PTF information
Jobs and job logs
Messages, message queues, message files
Users and groups
User spaces
System values
System status
In practice, we are using the IBM Toolbox for Java for Data queue communication.
More on this later!!
Framework
The Big Picture
1 – Double click Start_RPGToDesktop.bat on the PC to start the Java waiting/listening
process on data queue DQRPT2DT.
2 – From the command line (or other program process) the RPG2DT command is invoked and
a key specific to the corresponding listening PC is written to the data queue with the command
wishing to be executed.
3 – Java program RPGToDesktop.java is listening for new entries on data queue DQRPG2DT
and receives the event. Think of this as being similar to CHAINing to a keyed physical file,
except you “chain and wait” for a uniquely keyed record to be written, and once the record is
written, and your program is notified of the record, it is then deleted from the data queue.
4 – Java sends the command to the rundll.exe program running on the PC. Processing is
complete at this point.
Data Queue DQRPG2DT
Data queue DQRPG2DT is used to “connect” the RPG and Java program.
By specifying SEQ(*KEYED) I can have a single data queue facilitate all
users. This is possible because each user will be configured to have their
own unique id in the Start_RPGToDesktop.bat file.
When the Java program connects to the data queue and waits for entries,
it is waiting for entries with a specific key (i.e. 00001).
To create data queue DQRPG2DT:
CRTDTAQ DTAQ(RPG2DT/DQRPG2DT) MAXLEN(32766) SEQ(*KEYED) KEYLEN(15) AUTORCL(*YES)
Configuring the PC
Before you do anything else on the PC it is
necessary to configure the command that
starts the Java client program. Right click
on the Start_RPGToDesktop.bat file and
select Edit.
Start_RPGToDesktop.bat contents:
START javaw -cp jt400.jar;RPG2DT.jar com.mowyourlawn.RPGToDesktop
192.168.2.4 MYUSR MYPW RPG2DT DQRPG2DT 00001
The START javaw syntax invokes the Java process and keeps a DOS window from opening
up which can be quite annoying. The -cp is declaring that jt400.jar and RPG2DT.jar
should be included in our classpath. Think of a classpath being similar to a library list. If
something isn't in the classpath then Java doesn't know it exists.
com.mowyourlawn.com.RPGToDesktop is the full path to the Java class we wish to execute
within the RPG2DT.jar file.
The remaining text you see are parameters being passed into the Java process. Parameters
are delimited by a space. Change the IP address to be that of your IBM i and MYUSR and
MYPW to be a valid profile and password on the IBM i. Make sure the profile used has
authority to library RPG2DT to both use and create object DQRPG2DT.
Get Java –
Mmm... that sounds good.
You will need to make sure to have at least Java 1.5 (a.k.a
5.0) on your system to make this work.
To be safe you can head over to www.java.com and do the easy
download install process.
Starting the PC Process
The PC process is started by
invoking the
Start_RPGToDesktop.bat file in
the folder you unzipped.
Windows will recognize it as a MSDOS Batch File and appropriately
tries to invoke the contents which in
this case is the START javaw
command.
The RPG To Desktop window will be
displayed upon successful invocation.
If the DQRPG2DT data queue doesn't already
exist it will be created.
The client program will then go into a wait
state listening for commands sent from the
IBM i.
To end the process on the PC simply select the
usual 'X' in the upper right of the window.
Sending commands from IBM i
To send invocations to the PC we use the RPG2DT command. The below screen shot will open your
default browser to http://mowyourlawn.com.
Before using the RPG2DT command make sure to have library RPG2DT in your library list!
The UNQKEY(00001) parameter is the key (pun intended) to connecting with the PC as that is what
the Java process is listening for.
The PCCMD content is obviously fairly cryptic. Syntax for rundll32 can be found at the following URL:
http://vlaurie.com/computers2/Articles/rundll32.htm
Open Windows Control Panel
RPG2DT UNQKEY(00001) DQLIB(RPG2DT) DQNAM(DQRPG2DT)
PCCMD('RUNDLL32.EXE SHELL32.DLL,Control_RunDLL desk.cpl,,0')
Open Document on PC
RPG2DT UNQKEY(00001) DQLIB(RPG2DT) DQNAM(DQRPG2DT)
PCCMD('RunDll32.exe SHELL32.DLL,OpenAs_RunDLL c:\temp\test.pdf')
RPG2DT Command Source
Simple command used for interfacing with *PGM object RPG2DTR.
/* CRTCMD
CMD
PARM
PARM
PARM
PARM
CMD(RPG2DT/RPG2DT) SRCFILE(RPG2DT/QSOURCE) PGM(RPG2DTR) */
PROMPT('Call Desktop Command')
KWD(UNQKEY) TYPE(*CHAR) LEN(5) PROMPT('Unique Key')
KWD(PCCMD) TYPE(*CHAR) LEN(1024) PROMPT('PC Command')
KWD(DQLIB) TYPE(*CHAR) LEN(10) PROMPT('Data Queue Library')
KWD(DQNAM) TYPE(*CHAR) LEN(10) PROMPT('Data Queue Name')
RPG2DTR RPG Source
H dftactgrp(*no)
D RPG2DT
D ppUnqKey
D ppPCCmd
D ppDQLib
D ppDQNam
pr
D RPG2DT
D ppUnqKey
D ppPCCmd
D ppDQLib
D ppDQNam
pi
D QSNDDTAQ
D pDQNam
D pDQLib
D pDQLen
D pDQData
D pKeyLen
D pKeyData
pr
D
D
D
D
s
s
s
s
dqLen
data
keyData
keyLen
/free
5a
1024a
10a
10a
5a
1024a
10a
10a
extpgm('RPG2DT')
Simple RPG program used to send entries
(say commands) to the data queue being
listened to by the Java PC process.
This is ALL the code you need on the
AS400 side!
extpgm('QSNDDTAQ')
10a
10a
5 0 const
32766a
options(*varsize)
3 0 const
5a
5
3
0 inz(%size(ppPCCmd))
like(ppPCCmd)
like(ppUnqKey)
0 inz(%size(ppUnqKey))
QSNDDTAQ(
ppDQNam: ppDQLib: %size(ppPCCmd): ppPCCmd: %size(ppUnqKey):
ppUnqKey);
*inlr = *on;
/end-free
Java innards - “Main” method
This is the main method of the RPGToDesktop.java program. It receives in the parameters
specified in Start_RPGToDesktop.bat.
If the correct number of parms are not sent, it will gracefully display an error and exit.
If six (6) parms are sent, then the RPGToDesktop “Constructor” is called which is quite similar
to an *INZSR sub routine in an RPG program as it is only called once per invocation.
Note the windowClosing listener. This will allow us to end the program by clicking the 'X' in
the upper right hand corner.
Note statement s.listen() as we will be discuss it's contents later.
public static void main(String parms[]) {
}
if (parms != null && parms.length == 6) {
RPGToDesktop s =
"
new RPGToDesktop(parms[0], parms[1], parms[2], parms[3], parms[4], parms[5]);
s.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
s.listen();
} else {
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(
" com.mowyourlawn.RPGToDesktop <system> <user> <password> <DQLib> <DQName> <UniqueKey>");
}
System.exit(0);
Java innards – RPGToDesktop
(constructor)
This is the constructor method of the RPGToDesktop.java program. It
is utilized to create an “instance” of the RPGToDesktop object which we
saw was used in the previous main method. Creating an instance is
very similar to using LIKEDS in RPG – it creates something new based
on an existing definition.
Parameters are received in and applied to global variables for later use.
The graphical window is then created and configured using the new
TextArea() API call.
public RPGToDesktop(
String sys, String usr, String pw, String dqLib, String dqNam, String unqKey) {
super("RPG To Desktop");
this.sys = sys;
this.usr = usr;
this.pw = pw;
this.dqLib = dqLib;
this.dqNam = dqNam;
this.unqKey = unqKey;
}
commandWindow = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
this.add(commandWindow, BorderLayout.CENTER);
this.setSize(500, 200);
this.setVisible(true);
commandWindow.setEditable(false);
commandWindow.setVisible(true);
Java innards – listen method
1 – Connect to the IBM i using the profile and password specified on the initial call.
2 – Instantiate KeyedDataQueue object dq and attempt to create it to ensure it exists.
3 – Do a data queue read for a specific key (i.e. 00001).
4 – Command received. Convert it to from AS/400 native code pages to a Java String object.
5 – Start a new thread so the command can be run, and return for more data queue entries.
public void listen() {
1
2
host = new AS400(this.sys, this.usr, this.pw);
KeyedDataQueue dq = new KeyedDataQueue(host, "/QSYS.LIB/" + dqLib + ".LIB/" + dqNam + ".DTAQ");
try {
dq.create(5, 1024);
} catch (Exception e) {}
while (Continue) {
3
try {
KeyedDataQueueEntry dqData = dq.read(unqKey, -1, "EQ");
byte[] data = dqData.getData();
int Command_Length = 1024;
4
AS400Text textConverter = new AS400Text(Command_Length);
String Cmd_Str = (String) textConverter.toObject(data);
Thread t = new RunCommand(Cmd_Str.trim());
5
t.start();
}catch (Exception e) {
commandWindow.append("\nException " + e);
Continue = false;
}
}
host.disconnectService(AS400.DATAQUEUE);
}
Java innards – Inner class RunCommand
1 – This is the RunCommand constructor which was called in the listen method earlier to instantiate this object.
2 – The run method is expected to exist because we are extending the Thread class. When the listen method
invokes statement t.start(), then the Thread object will look for a method named run() and appropriately invoke it.
3 – Every Java application has a single instance of class Runtime that allows the application to interface with the
environment in which the application is running. The current runtime can be obtained from the getRuntime
method. After retrieving the runtime we immediately choose to call it's exec() method and pass in the command
originally received from the IBM i.
1
private class RunCommand extends Thread {
String cmd = "";
public RunCommand(String cmd) {
this.cmd = cmd;
}
2
public void run() {
String[] args = new String[4];
StringTokenizer st = new StringTokenizer(cmd.trim());
int i = 0;
while (st.hasMoreTokens() && i < 4) {
args[i] = (String) st.nextToken();
i++;
}
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {...}
return;
}
}
3
Future Enhancements
• Enhance RPG code to hide complexities of common
functions (i.e. Have a sub procedure named openBrowser()
that receives in a URL string)
• Create more examples that flex the muscles of RPG To
Desktop.
• Allow bi-directional communication.
• Anybody want to help?!
• Anybody have other features ideas?
Trouble Shooting
Problem: Nothing happens when I double click on the Start_RPGToDesktop.bat.
Solution: To display the console change the contents of Start_RPGToDesktop.bat to have the
following contents. Note the START was taken off and javaw was changed to just java.
java -cp jt400.jar;RPG2DT.jar com.mowyourlawn.RPGToDesktop [[don't change your parms]]
Problem: The Java process starts successfully, but none of the commands I enter on the
System i get executed on my PC.
Solution: Make sure that Start_RPGToDesktop.bat is using the same unique identifier as what
you are specifying on the System i (the last parameter in Start_RPGToDesktop.bat).
Side Note:Creating .jar files in Eclipse
To create an easy to move packaging of Java compiled classes you should
create .jar files vs. copying endless class files one by one.
Think of .jar files as being very similar to .zip files.
The download of RPGToDesktop includes the source, so you can create your
own Eclipse project and re-export it if you so choose.
To export, right click on the
Java project and select
Export.
Expand the Java folder and
select JAR file then click
Next.
Creating .jar files in Eclipse
Make sure the
RPGToDesktop.java file is
selected.
Select the check box to export
source.
Browse to your desktop and
provide the name
RPGToDesktop.jar.
Select to overwrite existing files
without warning.
Click Finish.
At this point you have a new
RPGToDesktop.jar file and can
now copy it to be in the same
directory as the jt400.jar and
Start_RPGTodesktop.bat files to
try out your changes.
Other Open Source Java
Try one of these out for yourself to see what you can do!
http://sourceforge.net/projects/jfreechart/ (Graphical charts)
http://jakarta.apache.org/poi/ (Excel Spreadsheets)
http://www.lowagie.com/iText/ (PDF creation)
http://www.eclipse.org/birt (Reports)?
http://www.pentaho.com/products/reporting/ (Reporting)?
Other IBM i Open Source Sites
http://rpgnextgen.com
http://www.opensource4iseries.com
http://iseries-toolkit.sourceforge.net
http://www.softlanding.com/websphere/rse.htm
http://www.scottklement.com/oss.html
http://www.martinvt.com/Code_Samples/code_samples.html
http://Netshare400.com
http://www.think400.dk/downloads.htm
http://home.alltel.net/craigru/jcrcmd2.html
http://sourceforge.net/projects/iseriestoexcel
http://www.rpgiv.com/downloads
http://www.code400.com
+
= Good things
We have reached the end!
Aaron Bartell
aaronbartell@mowyourlawn.com
lead developer of
RPG-XML Suite (www.rpg-xml.com)
and owner of
www.MowYourLawn.com
and check out his latest effort at
www.SoftwareSavesLives.com