Link to home
Start Free TrialLog in
Avatar of admiral
admiral

asked on

Runtime.exec()

UpdateVC4.bat is a batch file
that runs the ftp script Ftp4.txt

contents of UpdateVC4.bat:
echo Update price message being sent . Please wait ......................"

start ftp -s:Ftp4.txt


pause

exit


Contents of Ftp.txt:

//actual address omitted
open   000.000.000.000
anonymous  anonymous
bin

cd   d:\iFtpSvc\ussjccf5\users\outbound\

put  d:\iFtpSvc\ussjccf5\users\outbound\APIVALDTQ.txt    c:\iFtpSvc\ussjccf5\users\outbound\APIVALDTQ.txt

quit


The batch file works independantly when run from a command prompt and when the java application is run on my machine but in the test environment it doesn't

Java code that runs the script:

import java.io.*;


public class Ftp extends Thread {

  public Ftp() {
  // System.out.println("a new ftp created");
  }

  public void run()
  {
       Process p = null;
   //  String[] command = {"uploadVC4.bat"};

 
// I have also tried the following but the batch file is in the same directory
//as the application so the above  code should work

 /*  String[] command =  {"d:\\Rhythm\\Customer_Commitment_Suite\\InternetServer\\lib\\uploadVC4.bat"};  

 */
       System.out.println(" ftp started");
      //Runtime rt = Runtime.getRuntime();
   try {

        p = Runtime.getRuntime().exec(command);

        try{
        p.waitFor();
        } catch ( InterruptedException e ) {


        }
   } catch ( IOException e) {

  }


   p.destroy();
   p = null;
  }


}

exit
Avatar of Jim Cakalic
Jim Cakalic
Flag of United States of America image

The problem is likely to be that the environment of the test machine doesn't match the environment of your machine, particularly with respect to the definition of the PATH variable.

Runtime.exec(), at least on win32 systems, uses a version of CreateProcess that searches the directories defined in the PATH variable for the 'executable' file unless the filename defines a full path or a path relative to the current working directory. CreateProcess also looks in the current working directory.

Since you are probably running the interpreter having set your working directory to the location of the class and batch files, it is able to find both and your program executes. When you move the application to the production environment, this is no longer the case.

Try looking at the exception stack trace you get in the test environment. In the code you posted you are ignoring the exception so you should add e.printStackTrace() to the body of the catch block. I'm betting it will look something like this:

java.io.IOException: CreateProcess: junk.bat error=2
        at java.lang.Win32Process.create(Native Method)
        at java.lang.Win32Process.<init>(Unknown Source)
        at java.lang.Runtime.execInternal(Native Method)
        at java.lang.Runtime.exec(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at RuntimeExec.main(RuntimeExec.java:10)

The "CreateProcess: junk.bat error=2" is telling you that CreateProcess cannot find the specified file. Error=2 is familiar to old C hacks like me because it is the well known errno value for 'file not found'.

If this is the case, you have several possibilites, right? 1) Hardcode the path to the batch file (yuck). 2) Change the test (and subsequently production) environment to include the necessary paths. 3) Use ClassLoader.getSystemResource(String name) to find a named resource from the search path used to load classes. I'm not sure this last would work but, if so, it would look something like:

    ClassLoader cl = ClassLoader.getSystemClassLoader();
    URL url = cl.getSystemResource("UpdateVC4.bat");

Best regards,
Jim Cakalic
Avatar of admiral
admiral

ASKER

The error code produced by the
printStackTrace call was:


java.io.IOException: CreateProcess: junk.bat error=3  

What does 3 mean ?
 
After setting the path the error does not appear but the program does not execute.


     
Avatar of admiral

ASKER

Also when the absolute path is set in the exec call the program still does not run
Hi admiral,

When using Runtime.exec(), you can execute only executable files eg. EXE,COM,etc in Windows. You cannot "execute" a batch file . It is actually interpreted by the Command Line Interpreter "command.com" for Win95 & "cmd.exe" for WinNT. So try this

String[] command  =  {"command.com /c uploadVC4.bat"};

BTW if the contents of the batch file are the same then try

String[] command  =  {"start.exe","ftp","-s:Ftp4.txt"};
ASKER CERTIFIED SOLUTION
Avatar of Jim Cakalic
Jim Cakalic
Flag of United States of America image

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
Sorry, I forgot to say that win32 error code 3 is path not found -- the system cannot find the path specified.

Jim Cakalic
jim, can i call the above code from another java file ( removing the main & slapping the rest of your code into a method ) with same results?
Sure. With the exception of the reference to args, this section of code should be usable anywhere:

        Process p;
        try {
            p = Runtime.getRuntime().exec(args[0]);
            System.out.println("Found " + args[0]);
            InputStream is = p.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);
            String line = null;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int status = p.waitFor();
            System.out.println("Process exited (" + status + ")");
        } catch (Exception e) {
            e.printStackTrace();
        }

Best regards,
Jim Cakalic
Um -- well -- you probably don't want the System.out.printlns either :-) And you'll do something useful with the data piped back from the external process.
ok - yeah.. i did try this..  no deal..

problem i'm trying to beat is: from a servlet, call runtime.exec("net use lpt1: \\\\servername\\printername ")

i have this working in a standalone program, but it doesn't work from a servelt..  i'm playing with your file to try to somehow spit out my dos command..

any ideas??
Could it be a PATH problem? Have you tried specifying the full path to the net.exe file in the exec call? On my system (NT4) that is C:\Winnt\system32\net.exe. Are there any exceptions thrown? I'm not that familiar with servlet programming so I don't know where the stack trace for these would appear. I also don't know what possible restrictions there might be on servlets. Since they run on the server side, I'm guessing they have fairly unrestricted access to the system so security profile shouldn't be an issue ...