Wednesday, June 3, 2009

Program call: a practical example

In this post, I will show a practical example of using the jtopen plugin to call a program on the AS/400.

We will create a grails service to execute commands on the AS/400.

We assume we have a grails application with the jtopen plugin installed.

We first have to set the AS/400 host, user and password. We will edit the grails-app/conf/Config.groovy file and add the three following lines:
jtopen.as400 = 'as400'
jtopen.user = 'user'
jtopen.password = 'password'
Of course, you should customize the values to your environment. As they are typically per-environement values, we will set them with the grails.serverURL variable.

We then create a new service:
grails create-service Command

This will create the file grails-app/services/CommandService.groovy, we will change it to:
import org.codehaus.groovy.grails.plugins.jtopen.types.*
class CommandService {
boolean transactional = false
def ibmI

def executeCommand(String command) {
def cr ='QCMDEXC',[
new IChar(command),
new IPacked(command.length(),15,5)] as Type[])
And that's it!
Let's have a closer look.

import org.codehaus.groovy.grails.plugins.jtopen.types.*
We import the parameter types used to call the program.

def ibmI
This line creates a property named ibmI. It will automatically be injected with an IbmI object.

def cr ='QCMDEXC',[
new IChar(command),
new IPacked(command.length(),15,5)] as Type[])
Here is the heart of the service. This will call the QCMDEXC API with the two parameters it expects:
  • The command to execute as a CHAR variable
  • The command length as a (15,5) packed decimal
You can see that the QCMDEXC parameters are surrounded by [ and ] as Type[]. This is necessary because of a bug in groovy. This bug has been fixed in the groovy trunk and this circumvention shouldn't be necessary in future grails releases.

This line makes the service return true if the command execution is successful or the array of messages returned by the command will be returned.

Now let's create a controller using this service:
grails create-controller DataArea

This will create the file grails-app/controllers/DataAreaController.groovy, change it to:
class DataAreaController {
def commandService
def create = {
def result = commandService.executeCommand("CRTDTAARA ${} TYPE(*CHAR) LEN(10)")
render result==true?"Data area ${} created":result.inspect()
We now start the application:
grails run-app

Now point your browser to:

You should see the message "Data area grails created". On your AS/400, you should have a data area named grails in the jtopen.user user current library (or QGPL).

That's all for this example.


  1. Just wondering, why did you not use something like this?

    cc = new CommandCall(AS400_obj)"CRTDTAARA ${}")

  2. Never mind. I see that it a program call. Nothing to do with a command call.

  3. Hi Damien.
    What about a plugin that convert DDS records like IBM webfacing Tool, do you know?
    It will be a very good open-source project to web-enabled RPG with Grails.
    Are you interested in?

  4. Hi Damien.
    Can you give me some example to call a program with input and output parameter?
    There are other doc/example resources about this plugin?
    How can i convert for example a IPacked to BigDecimal for print it?