Link to home
Start Free TrialLog in
Avatar of robin_smith123
robin_smith123

asked on

running cl command from java

i have to execute cpytoimpf command from my java code ...can some1 tell me how to do that from java.my application is in as/400 only.should i use jt400.jar or something else.Plz Help
Avatar of Kevin Cross
Kevin Cross
Flag of United States of America image

I have NOT programmed Java on AS/400 myself, but know that colleagues of mine did it all the time; therefore, I would check out the API as it may have something useful in there.  You can try this: http://publib.boulder.ibm.com/html/as400/v4r5/ic2924/index.htm?info/java/rzaid/jvastart.htm.

Normally from Java to run a command line on underlying system, you use Runtime.exec() so you can give that a shot.

But I know CL programming in AS/400 is not necessarily same as passing command to command line, so link will probably help.
You can either use IBM iSeries Toolbox for Java (jt400.jar), or the equivalent open-source JTOpen project.  

http://www-03.ibm.com/systems/i/software/toolbox/

Either way:

Kevin Vandever's article should get you right where you need to go, with sample code and all:

http://www.itjungle.com/mpo/mpo060602-story06.html

- Gary Patterson
Avatar of robin_smith123
robin_smith123

ASKER

S400 system = new AS400(dbname, username, pwd);
                        try{
                       
 i m using jt400 only but it gave me exception,
"command property not set"      
My application is on as/400 only ,can i use java.runtime.exec          




CommandCall command = new CommandCall(system );
command .run("CPYTOIMPF FROMFILE('DB/EMPLOYEE') TOSTMF('fileName.csv"')   STMFCODPAG(37) MBROPT(*ADD) RCDDLM(*CRLF) DTAFMT(*DLM) STRDLM('\"') FLDDLM(',') DECPNT(*PERIOD) DATFMT(*ISO) TIMFMT(*ISO)");
command.run("another cpytoimpf command");
}
catch(Exception e)
{
      System.out.println("error in command - " +e);
}
i m using jt400 only but it gave me exception,
"command property not set"      
My application is on as/400 only ,can i use java.runtime.exec          




AS400 system = new AS400(dbname, username, pwd);
                        try{
                       
 



CommandCall command = new CommandCall(system );
command .run("CPYTOIMPF FROMFILE('DB/EMPLOYEE') TOSTMF('fileName.csv"')   STMFCODPAG(37) MBROPT(*ADD) RCDDLM(*CRLF) DTAFMT(*DLM) STRDLM('\"') FLDDLM(',') DECPNT(*PERIOD) DATFMT(*ISO) TIMFMT(*ISO)");
command.run("another cpytoimpf command");
}
catch(Exception e)
{
      System.out.println("error in command - " +e);
}
ASKER CERTIFIED SOLUTION
Avatar of Member_2_276102
Member_2_276102

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Tom's got it mostly right,  (I think those are double quotes, not extra singles).

Needs to be:

TOSTMF('fileName.csv')

and

STRDLM('\')

And you should be golden.

- Gary Patterson
Haven't tried it, but my guess is that java.runtime.exec will probably run in the Qshell environment, so you would need to use Qshell commands instead of native OS/400 commands.  If my guess is right, you can use the Qshell "system" command to run a CL command:

http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=/rzahz/system.htm

If you try it, please post the results back.  I'd be curious.

- Gary Patterson
Ah, found a link:  Calling a CL program, a CL command, or a Qshell utility from runtime.exec:

http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/rzaha/javalang.htm

- Gary Patterson

guys actually command is functioning fine in my program .....i mean it executes fie but with the exception,"command property not set" ......has any 1 tried calling cl command from java ....and those syntax error is due to my tyoing mistake here in the post.
Hard to tell from your example, since it is apparently not the "real" code that you are executing.  I use the syntax below.  If I have more than a few commands to execute, I write a CL program and call it from Java.  That way I can also do my CL error handling right in the CL program, without having to go back and handle it in Java.

If you need more help, I suggest you post the actual code you are executing, plus the full output produced when you execute and get the error.

- Gary Patterson






AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
try
{
   CommandCall.run(system, "COMMAND 1");
   CommandCall.run(system, "COMMAND 2");
...

Open in new window

whats system in the abobe command example
CommandCall.run(system, "COMMAND 1");

whats "system" in the above command example
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
CommandCall is a static function, so you are just telling it to run it on the object representing your AS400 that you instantiated with credentials as shown above.

if i just write
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
 CommandCall.run("command");

is it write syntax
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
How can i make sure that the command has completed successfully,and it does not make server to slow down.
CPYFRMIMPF  FROMSTMF('folder/filename') STMFLEN(*TOFILE) TOFILE(schema/tablename *FIRST) MBROPT(*ADD) RPLNULLVAL(*NO) RMVBLANK(*LEADING) RCDDLM(*ALL) DTAFMT(*DLM) STRDLM('"') FLDDLM('|') DECPNT(*PERIOD) DATFMT(*ISO) TIMFMT(*ISO) ERRLVL(*NOMAX) ERRRCDOPT(*REPLACE)

wht doz "ERRLVL(*NOMAX)" and  "ERRRCDOPT(*REPLACE)" attributes do in the above command,I havent created any errorrecord file.Do i need these attributes in the command.can some tell me the use of these 2 attributes clearly.
Use the getMessageList method to get messages returned by the command:

http://publib.boulder.ibm.com/infocenter/iadthelp/v7r0/index.jsp?topic=/com.ibm.etools.iseries.toolbox.doc/cmdcallex.htm

As far as "slowing the server down", it depends on a lot of things:

How many records you are loading.
How many indexes and views there are over the target table.
How many trigger programs get invoked as a result of your data import and what those trigger programs do.
How big your system is.
How busy your system is at the moment.
How fast the communications line is between the source and destination systems.
How your database server jobs are configured for performance.
And other variables.

In general,  if your command runs fast, it is probably not having much impact.  If it takes a long time to complete, you may want to monitor system performance and determine if this needs to be run off-hours.

(I already answered your ERRLVL and ERRRCDOPT questions in another post.  Please do not post duplicate questions like this.)

- Gary Patterson

whats the meaning of BCI job.Actually some BCI  job is eating away cpu's time while our java application runs.
its says its QZDNOIT job ..can some 1 tell me how to tackle this
BCI jobs are server jobs. They respond to requests from other applications and systems.

Do you mean "QZDASOINIT"?  I don't know what "QZDNOIT" is.

If so, those jobs process ODBC (Open database connectivity) requests from client applications.  If your Java jobs use SQL  via ODBC/JDBC to access the AS/400 database, then this is your culprit.

You'll probably need to do some performance analysis and tuning of your Java application and the SQL statements that it executes to resolve the issue.  There are a lot of things that be done to improve application performance, but it depends on the application.

Application and database performance tuning is a big, complex topic.  If you want to post the Java program in question, I might be able to make some suggestions of things to look at.

The Redbook listed below explains how to gather database performance information, and explains the tools and techniques that you can use to diagnose and resolve database performance issues.

Here are some ODBC/JDBC/SQL performance links:  

iSeries ODBC Performance
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=/rzaik/rzaikodbcperfconsd.htm

iSeries JDBC Performance

http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzaha/jdbc.htm

iSeries DB2 UDB SQL Performance Redbook
http://www.redbooks.ibm.com/abstracts/sg246654.html

If you don't have AS/400 application and database performance experience, you may want to consider bringing in an experienced consultant or trainer.  It can be complex.

- Gary Patterson
CommandCall command = new CommandCall(system );

command .run("CPYTOIMPF FROMFILE('DB/EMPLOYEE') TOSTMF('fileName.csv"')   STMFCODPAG(37) MBROPT(*ADD) RCDDLM(*CRLF) DTAFMT(*DLM) STRDLM('\"') FLDDLM(',') DECPNT(*PERIOD) DATFMT(*ISO) TIMFMT(*ISO)");
command.run("another cpytoimpf command");

Is it the right way to execute multiple cl comands from java.Actually i want that 2nd command executes only after the 2nd command has been executed successfully on as/400.
Is there any way i come to know that the first command has executed succussfully.
And also can i create a cl program and call it from my java code so that commands r executed one by one .
can some one give me sample cl progarm where i can put these commands and tell me how to compile that program and call from java .i have very less knowledge of cl programs .Pls help
CommandCall command = new CommandCall(system );

command .run("CPYTOIMPF FROMFILE('DB/EMPLOYEE') TOSTMF('fileName.csv"')   STMFCODPAG(37) MBROPT(*ADD) RCDDLM(*CRLF) DTAFMT(*DLM) STRDLM('\"') FLDDLM(',') DECPNT(*PERIOD) DATFMT(*ISO) TIMFMT(*ISO)");
command.run("another cpytoimpf command");

Is it the right way to execute multiple cl comands from java.Actually i want that 2nd command executes only after the 1st command has been executed successfully on as/400.
Is there any way i come to know that the first command has executed succussfully.
And also can i create a cl program and call it from my java code so that commands r executed one by one .
can some one give me sample cl progarm where i can put these commands and tell me how to compile that program and call from java .i have very less knowledge of cl programs .Pls help
robin_smith123:

It's still not clear if you're deliberately trying to create a file with a double-quote as part of the name -- TOSTMF('fileName.csv"'). Are sure you don't want TOSTMF('fileName.csv') instead?

Although it can be done, it sure adds a lot of potential complexity.

Tom
Robin_smith123:

1) I usually use a separate commandCall object for each command, so I don't know what happens of you try to repeatedly execute the run method with different command strings specified.

2) Use the messageList method to see if there were any error messages returned by the AS/400 command.  Here's good sample code that includes testing for successful execution, plus checking for AS/400 messages:  

http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=/rzahh/commandcallexample.htm

3) If you need to run a series of CL commands, it is easiest to create a CL program and call that program.  There is a basic tutorial on creating a CL program starting on p162 of the CL Programmer's Guide:

http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/rbam6/rbam6.pdf

- Gary Patterson







can some one give me a "simple cl program with statements  in my code snippet" and how to compile it in as/400 and call it from java .
Sure,

Like I said above, go to page 162 of the CL Programmer's Guide above for step-by step instructions for creating and compiling a short CL, complete with a short sample CL program to type in.

Then call it using the same Java program you posted above, but change the "CYPTOIMPF" command to a "CALL" command.

- Gary Patterson

Here is a sample CL.  It is just a list of commands that you want to execute, like a DOS BAT file.  Of course, you can get fancier with parameter passing, variables, loops, conditions, I/O, error handling, procedures, program calls, and more, but you'll need to take a class or buy a book for all of that.
 
PGM
  WRKSPLF
  WRKACTJOB
  DSPJOBLOG
ENDPGM
 
Here's a little more sophisticated CL program:
 
PGM
   /* Declare variables */
   DCL &USER *CHAR 10                /* USER PROFILE */
   DCL &LIBEXISTS *LGL VALUE('1')    /* LIBRARY EXISTS FLAG */
 
   RTVJOBA USER(&USER)               /* GET CURRENT USER'S PROFILE NAME */
 
   CHKOBJ OBJ(&USER) OBJTYPE(*LIB)   /* DOES LIB W/SAME NAME AS USER PROFILE EXIST? */
      MONMSG CPF0000 EXEC(CHGVAR &LIBEXISTS '0')  /* If not, set variable to '0' */
 
   ADDLIBLE   LIB(INTRO)             /* Add INTRO to library list */
   IF &LIBEXISTS +                   /* If personal library exists, add it to the libl */
      ADDLIBLE   LIB(&USER)
 
   TOP:                              /* Finally, start PDM and stay in PDM even if user exits */
      IF &LIBEXISTS +                
         WRKOBJPDM LIB(&USER) OBJ(*ALL) OBJTYPE(*FILE) OBJATR('PF*SRC')
      ELSE +
         STRPDM
   GOTO TOP                          /* Endless loop until user logs off */
 
ENDPGM
 
Here is the Java:
 
AS400 system - new AS400(a,b,c,d);                  
command commandCall = new commandCall(system);
command.run("CALL mylib/myprogram");
 
Where mylib is the library where you compiled your CL and myprogram is the name of the CL you created.
 
- Gary Patterson

Open in new window

where i have to provide the name of the pgm and how to compile that
i mean while creating a pgm where we have to specify the name of the pgm and how to compile it
You name a program when you compile it using the CRTCLPGM command the "PGM" parameter contains the name of the target library and the name of the program.

- Gary Patterson
Can i know how to write a parameterized pgm.
But my main issue is to just running those 2 commands only when the first command has finished .Isnt there any way through java i can control that .Has any one worked extensively with CommandCall class .I dint find much examples on the internet.
Robin,

This question is getting "big".  I suggest you please post another question if you need help writing a parameterized CL.

I've used CommandCall extensively. For your application, I suggest that you create a class that runs ONE command and handles errors the way you want them handled (console message, log file, exception whatever).  Then your code would look something like this:

if myCommandClass.run("COMMAND1 GOES HERE")
   myCommandClass.run("COMMAND2 GOES HERE")

Where myCommandClass is the class that you created to run the AS/400 command and handle errors.

That said, if you just want a block of code that runs two commands and prints errors and exceptions, try this:

1) Run the first command (you already know how to do that).
2) Use the messageList method to check for errors.  (See the example link above.)
3) If there are no errors, create a new CommandCall object (see below) and run the second command.  I suggest that you don't try to reuse the same CommandCall object since that seems to be giving you trouble.
4) Use the messageList method to check for errors on the second command, if needed.

- Gary Patterson

AS400 system = new AS400(dbname, username, pwd);
CommandCall command1 = new CommandCall( as400 );
 
      try
      {
         // Run the command.
         if (command1.run("COMMAND 1 GOES HERE"))
             System.out.print( "Command 1 successful" );
         else
             System.out.print( "Command 1 failed" );
 
         // If messages were produced from the command, print them
         AS400Message[] messagelist = command1.getMessageList();
         if (messagelist.length > 0)
         {
             System.out.println( ", messages from command 1:" );
             System.out.println( " " );
         }
 
         for (int i=0; i < messagelist.length; i++)
         {
            System.out.print  ( messagelist[i].getID() );
            System.out.print  ( ": " );
            System.out.println( messagelist[i].getText() );
         }
      }
      catch (Exception e)
      {
         System.out.println( "Command " + command1.getCommand() + " did not run" );
      }
 
CommandCall command2 = new CommandCall( as400 );
 
      try
      {
         if (command2.run("COMMAND 2 GOES HERE"))
             System.out.print( "Command 2 successful" );
         else
             System.out.print( "Command 2 failed" );
 
         // If messages were produced from the command, print them
         AS400Message[] messagelist = command2.getMessageList();
         if (messagelist.length > 0)
         {
             System.out.println( ", messages from command 2:" );
             System.out.println( " " );
         }
 
         for (int i=0; i < messagelist.length; i++)
         {
            System.out.print  ( messagelist[i].getID() );
            System.out.print  ( ": " );
            System.out.println( messagelist[i].getText() );
         }
      }
      catch (Exception e)
      {
         System.out.println( "Command " + command2.getCommand() + " did not run" );
      }

Open in new window

pls can i know how to write parameterized cl program.Ur sample java program is fine but i guess ,when the command starts executing on as/400,cmd.run() returns true .it doesnt returns true when the command has finished executing.i think i have to use actioncompletedlistner function of commandcall class to achieve my objective.I wil keep u updated whether it worked or not.
Try using the setThreadsafe() method to force the command to run in the current thread.  CPYTOIMPF/CPYFRMIMPF are not thread safe, so they get handed off by CommandCall to a service, where they run outside of your process.  If you can force the command to run in the current thread, it will run inline.

You will need to take steps to insure that two instances of the run() method are executing your CPY command at the same time if you override thread safety.

Not all commands will run successfully using the setThreadSafe() method.

If that doesn't work, then you will need to add a listener to monitor for command completion.

- Gary Patterson
Sure.  I spent a lot of time on this and provided correct, detailed responses at every step.  I propose you split the points evenly between the three experts that contributed, since we all provided valuable input.

- Gary Patterson
I have no interest in points from here; I merely commented for minor clarification.

IMO, Gary deserves major points.

mwvisa1 attempted to offer help, but had difficulty getting clear dialog in return. Effort seemed correct as far as it could go and should be compensated.

The thread itself has sufficient valuable info to argue against deletion.

Tom