PDA

View Full Version : Java-Methoden und RPG Hilfe!!!!!!!



Nasenbär
21-05-03, 09:13
hi, ich habe folgendes problem. ich möchte aus einem RPG-Programm Java-Methoden aufrufen weiß aber nicht wie ich die Klassenpfade anzugeben habe! kann mir da jemand helfen oder kennt jemand eine gute doku zu diesem thema java in RPG??

vielen dank!

TARASIK
21-05-03, 09:32
Hallo Nasenbär,
vielleicht hilft das einwenig:

Calling a Program Using the iSeries Toolbox for Java
by Kevin Vandever
More and more, those who develop outside the iSeries are required to access business rules written on the iSeries. They've always understood that data exists on that weird black box but like to dismiss the business rules. You see, accessing legacy applications doesn't excite non- iSeries programmers. It's not sexy. But it makes good business sense, and makes for good code reuse, too. The good news is IBM's iSeries Toolbox for Java provides tools to access a variety of iSeries services, like calling programs. And using the Program Call Markup Language, an XML extension, simplifies and standardizes the process, and may even make it a little sexy.






What Is the Toolbox?
The iSeries Toolbox for Java is a set of JAR files that contain the necessary Java classes used to access iSeries resources. You can think of JAR files much like you do Zip files, because that's what they really are. JAR files are used to store the classes, images, and whatever else is needed in a compressed format for downloading and installation ease. You can download the Java toolbox, JTOPEN, containing iSeries- specific classes, from IBM's toolbox site. Or, if you have the Java Toolkit (5722-JV1) installed on your iSeries, you can run everything from your iSeries. Other options you have are to install the WebSphere Development Studio (5722-WDS) tools on your PC (which comes with the AS/400 Java toolkit as well as IBM's version of the Java SDK), or you can copy the iSeries' 5722-JV1 JAR files to your PC from the iSeries Integrated File System. Regardless of how you get the Java SDK and the iSeries-specific Java classes there, once installed, you point your CLASSPATH to where the toolbox is installed so that the Java compiler and the Java runtime commands can find them. More about that later. Then you can use the classes contained within the toolbox as you would any other Java class, as they are 100% Pure Java.
Calling iSeries Programs
In this article, I am going to show you how to call a simple RPG program, but everything you learn here can be used to call any iSeries program--even COBOL. There are two ways to directly call an iSeries program using the Java toolbox. The first involves creating an array of parameter objects inside your Java application and properly converting the data from Java format to the correct iSeries format. It works just fine and was the only method used to call iSeries programs up until V4R2. Then there came a new sheriff to town, Program Call Markup Language. PCML is an extension of XML. PCML handles the program call and parameter definitions for you. Although each technique is still used, PCML is becoming the standard method for calling iSeries programs, and it is the method I am going to explain in this article. Who knows, there may be a future Midrange Programmer article written to explain the original method used to call iSeries programs (that's called a tease, in the business world).
PCML Basics
As I mentioned, PCML is an extension of XML, which has become the standard for transporting data across disparate as well as similar platforms. PCML allows you to remove the definition of the program and its parameters from the Java code and place them inside an easily readable, tag-based document that is then generated into PCML class objects. These PCML class objects handle the calling of the program, the retrieval of the data from the program, and the conversion from iSeries data to Java objects--all of which are tasks you had to code inside your Java program before the introduction of PCML. For my example, I am going to call an RPG program with four parameters. I am going to send the program two numbers to add, and it will return the sum of those numbers and a comment, just to show that you that you can use different data types. The following PCML will be used to call the RPG program:
<pcml version="1.0">
<program name="program" path="/QSYS.lib/YOUR_LIBRARY.lib/PROGRAM.pgm">
<data name="parameter1" type="zoned" length="6" precision="0"
usage="input"/>
<data name="parameter2" type="packed" length="9" precision="2"
usage="input"/>
<data name="sum" type="packed" length="9" precision="2"
usage="output"/>
<data name="comment" type="char" length="20"
usage="output"/>
</program>
</pcml>
The first line defines the version of PCML that is used. That line is required. As for the rest, PCML is made up of three tags: the program tag, the struct tag, and the data tag. Notice the PCML has a program tag and data tags but no struct tags. That is because the struct tag is used to pass or retrieve array typed data. We don't have that in this program. Each of these tags can be further expanded by attributes. For instance, the program tag can be expanded using the name, path, parseorder, and threadsafe attributes. There are two other attributes, but they can be used only when calling service programs, which I will discuss in a future article (another tease).
PCML Tags
In my example, I am only interested in the name attribute, which defines the program name--in this case PROGRAM--and the path attribute, which tells the PCML where the program resides on the iSeries. The parseorder attribute allows you to tell which output parameter to process first. The default is to process in the order they are entered in the PCML document. This might come in handy when one parameter returns information about a previous parameter. You may then want to change the processing order. The threadsafe attribute is used when you are calling an iSeries program from a Java application on the same server. In that case, you may want to call the iSeries program in the same job and on the same thread as the Java program. This may result in better performance but will only work if the iSeries program is threadsafe. Again, you don't need to use the parseorder or threadsafe attributes in this example, but I thought I would explain them anyway.
Now it's time to define the parameters. This is done using the data tag and its attributes. The data tag can be further expanded by the following attributes:


Type Type of data
Bidistringtype Bidirectional string type for character variables (the default is blank, which will use the CCSID
CCSID The host's coded character set ID
Count Specifies that the element is an array, and this specifies the number of entries
Init Specifies an initial value for the data element
Length Specifies the length of the data element
Maxvrm Specifies the highest version of OS/400 where this element exists
Minvrm Specifies the lowest version of OS/400 where this element exists
Name Specifies the name of the data element
Offset Specifies the offset to the data element within an output parameter
Offsetfrom Specifies a base location from which the offset value is derived
Outputsize Specifies the number of bytes to reserve for output data for this element
Passby Passed by reference or by value (valid only with service program calls)
Precision Specifies the number of bytes for numeric data
Struct Different from the struct tag, this attribute is used to name a structure element for this data element
Usage Specifies whether the parameter is input, output, inputoutput, or inherit

As you can see, there are a number of attributes that can be used with the data tag. In my example, I use name, type, precision, length, and usage. The good news--for iSeries programmers, anyway--is that you define these parameters using iSeries data types, such as packed and zoned. Notice after each data tag is defined, the line is ended with an end tag (/>). This signifies the end of a tag. I didn't code the end tag symbol on the program tag line, because all the data tags are for this particular program and are therefore included with the program tag; so, I won't code the end program tag until after I define all the parameters.
OK, so most of the data attribute stuff is straightforward, right? I've defined a couple of packed fields, a zoned field, and a character field just to show that I could. However, be cautious when using the usage attribute. Usage really matters when employing PCML. We iSeries programmers are accustomed to our parameters being input/output, and you can certainly define them that way in PCML, but you don't have to.
Notice that I defined the first two parameters as input. These parameters are used only for input into the iSeries program, so I only want input values created. I defined the last two parameters as output because they are results passed back to my Java application from the iSeries program, and therefore I only want output values created for them. I could have defined them all as inputoutput, but if you do that, both input and output values will be created for these data elements even if you don't really need both. This might impact performance, but it definitely creates objects that aren't needed.
Now that all the data elements have been defined, it's time to code the end tag (/>) for the program tag and then the PCML tag. Once this document is created, save it with an extension of .pcml and place it in the same directory where your java class will exist. Let me repeat that: Place the PCML document in the same directory as your Java class! One final note: If you save it with the name ExamplePCML.pcml, you won't have to modify the Java code included with this example.
Java and PCML
The complete Java source code for this example, as well as the RPG and PCML source, can be downloaded from www.midrangeserver.com/downloads/mpo011702-story04.zip. (http://www.midrangeserver.com/downloads/mpo011702-story04.zip.) What I specifically want to show you, however, is the Java source that relates to the toolbox and PCML. If you'd like to download the code and have it next to you as you read on, I'll wait.... Now that you have the code in front of you, take a look first at the first four lines:
import com.ibm.as400.data.ProgramCallDocument;
import com.ibm.as400.data.PcmlException;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Message;

These lines allow you to import the necessary classes required to connect to the iSeries, to use PCML, and to retrieve iSeries messages and PCML exceptions. Once you have the necessary imports defined, you'll next want to create a new AS/400 object, instantiate that object, set your input parameters, and call the program. The following code will accomplish those tasks:
AS400 sys = new AS400();
pcml = new ProgramCallDocument(sys, "ExamplePcml");
pcml.setValue("program.parameter1", new Integer("5"));
pcml.setValue("program.parameter2", new BigDecimal("5.25"));
rc = pcml.callProgram("program");

What I've done here is to create an AS/400 object called sys and instantiated that object with new AS400(). By placing nothing between the parentheses, I will be prompted for a system, user ID, and password when the program is called. You can optionally add parameters between the parentheses to fill in details about the iSeries connection and therefore save the users from keying it in every time they call the program. For example:
AS400 sys = new AS400("url of iSeries", "user id", "password");

Instantiating the AS/400 object in this manner would directly connect without prompting. You can also leave any parameter out, from right to left, to fit your needs. If you left the third parameter blank, you would be prompted, but the system name or IP address and user ID would be filled in, leaving only the password to be entered.
Next you create a new PCML object and give it the AS/400 object name, sys, and the PCML document name, ExamplePCML. Next you set the PCML object input parameters using the setValue method from the PCML object. Notice that the parameter names and program match those in the PCML document. The last thing you do is call the program, with the callProgram method, from the PCML object. Done, right? Well, not exactly. When you get the results you are looking for, you will have to know how to retrieve the values from the program call. First, however, there are a couple of things you can do just in case you get errors on the call.
The following code can be used to retrieve messages from the iSeries if something went wrong with the call:
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("program");

// Loop through all messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("Call to PROGRAM failed. See messages listed above");
System.exit(0);
}

If you look back at the actual call, I used a return code of rc to capture whether or not the program ran successfully. If it didn't, rc will equal false and I will want to retrieve my messages. I created an AS400Message array object, called msgs, and instantiated it with the getMessageList method from the PCML object. Notice my program is the only parameter for the method call. Once the message list is retrieved, you can determine how many messages there are with the length method in the msgs object and loop through the messages, sending them to standard output. Then I print a message to let the user know that the program failed and to see the message just printed. In most cases, standard out might be a log file, but for the purpose of my example, I just spit them out to the screen.
If everything ran smoothly, the following code will retrieve and present your results:
else
{
// Process the returned Data
sum = (BigDecimal) pcml.getValue("program.sum");
comment = (String) pcml.getValue("program.comment");

System.out.print("5" + " + " + "5.25" + " = " + sum);
System.out.print("\n");
System.out.print(comment);
System.exit(0);
}

Pretty simple stuff, huh? The two output parameters, sum and comment, are defined as Java data types and instantiated with the getValue method from the PCML object. The getValue method is used for each output variable defined in the PCML document. Another way to define the Java variables sum and comment would have been to define them as objects with the other object definitions above, and use them here without the Java types placed in parentheses. It's up to you.
Compiling and Running
There are a couple of things to keep in mind before compiling and running your application. If you are planning to run your app in a Windows environment, you must first tell the operating system, and possibly your development environment, how to find your Java environment. I coded and compiled my Java application using CODE/400 on Windows 2000. Before I could successfully do this, I had to set my PATH environment variable to tell CODE/400 where to find my Java environment. If you use WebSphere Development Tools, you can add the following to your PATH environment variable:
SET PATH=%PATH%;C:/WDT400/Studion35/bin

Your setup might be different, or you might not use CODE/400 as your development environment, so make sure to find where your javac command is stored before modifying your PATH environment variable. The next thing you'll want to do is set your CLASSPATH environment variable to tell it where your toolbox JAR files reside. In my case, jt400 and data400, which are the JAR files needed to use PCML in the iSeries toolbox, reside in C:\WDT400\java. So the entry in my CLASSPATH environment variable would be the following:
SET CLASSPATH=%CLASSPATH%;C:\WDT400\java\jt400.jar;C:\ WDT400\java\data400.jar

On the toolbox Web site mentioned earlier, there is a choice to download toolbox documentation. I suggest that you do this. It will not only tell you how to work with the toolbox but also explain how to manually install the JAR files and tell you which JAR files contain which classes for which iSeries services.
On the iSeries, the CLASSPATH is configured automatically when you install the Java Development Kit (JDK) and the iSeries Toolbox licensed programs. If you have other Java classes that you want to access, or you've copied the toolbox or JDK to your iSeries, you can modify the CLASSPATH either in the Qshell environment or from a command line using the Work with Environment Variables (WRKENVVAR) command, or in a CL program using the ADDENVVAR command.
That's All I Have to Say About That
I've covered a lot of material here, but I hope you will come away with a basic understanding of how to call iSeries programs from Java using PCML. Once you get your hands on the toolbox, download my code and play around with it to see how it works. In addition to the actual code, I've also tried to give you a little information on how to install and implement the toolbox. Getting the CLASSPATH and PATH environment variables correct may seem a little confusing at first, but think of it as your library list. You can't very well run an iSeries program unless you qualify it or it exists in a library in your library list. The same holds true for Java. The classes must either be qualified when you run them with the Java command or be resident in the path-related environment variables. Tune into future articles on how to access the other iSeries services using the iSeries Toolbox for Java. I know; I'm such a tease.
Kevin Vandever is a lead IS engineer for Boise Cascade Office Products in Itasca, Illinois, and co- editor of Midrange Programmer, OS/400 Edition. He can be reached at kvandever@midrangeserver.com.

Gruss TARASIK

Nasenbär
21-05-03, 09:55
Danke dir erstmal für die schnelle hilfe aber ich arbeite nicht mit Code/400! es hat mir leider nicht viel geholfen! muss man fremde klassen in einem bestimmten verzeichnis in der as ablegen?

scr
22-05-03, 09:56
Hallo,

der CLASSPATH kann mit WRKENVVAR verwaltet werden. Dort als Environment-Variable mit Auswahl 1 die Variable CLASSPATH und den Pfad hinzufügen.

Gruß,
Dieter.