1

I have a java code that takes a data file, copies the data to a perl script, and calls the perl script from a shell script. Here is the relevant code:

    public String returnStringForPerlScript(ArrayList<String> arrayContainingPerlScriptArguments, String singularFilePath) throws IOException{
    String argFileName = null;//5
    String argParsedFileName = null;//
    argParsedFileName = arrayContainingPerlScriptArguments.get(4);
    argFileName = arrayContainingPerlScriptArguments.get(5);
    System.out.print("ARG1: "+argFileName);
    System.out.print(" ARG2: "+argParsedFileName);

    String runCmdString = singularFilePath+"perlscript.pl";
    String runCmd  = singularFilePath+"runPerlScript.sh";


    return runCmd;
}

The code above is a method in a separate class. The code below is where the Process is actually initialized and ran.

p = dfp.returnStringForPerlScript(perlParam, singularDirectoryPath);
System.out.println("Running from: "+p);
process = Runtime.getRuntime().exec(p);

What is confusing is that this code worked perfectly well earlier, and all I changed is the output directory. Instead of "singularDirectoryPath", I had written out a completely different file path. I am very confused because I have no idea what is wrong with the code, considering it ran before. When I called "runPerlScript.sh" from the terminal, it worked.

I also should add that I did try to use a String[] instead of a string, as shown below:

    String[] cmdArray = {"/bin/tcsh","-c","/filepath/runPerlScript.sh"};
    Process p = Runtime.getRuntime().exec(cmdArray);

Still did not generate any output files.

8
  • Neither a shell script or a perl script is a real executable file. They rely on a shell, which exec() has nothing to do with. Commented Jul 25, 2013 at 21:05
  • possible duplicate of to run shell script through java Commented Jul 25, 2013 at 21:06
  • When you say that it does not work what does it actually do? Does it throw an error? If yes can you add the stacktrace? Please also describe what value it used to take as a parameter (when it worked), what was the new value you changed now and the output of the print statements would be nice Commented Jul 25, 2013 at 21:08
  • @c.s Sorry, I should've been more specific. I meant that when I say it didn't work, I am comparing it to when output files were generated vs now when output files are not generated. Before, many output files were generated when I called the shell script. Now, no output files are generated when I call the shell script. Furthermore, no error is thrown whatsoever. The only value I changed was "singularDirectoryPath", which just basically changed the directory where the runPerlScript.sh script should be called. Commented Jul 25, 2013 at 21:15
  • @BrianRoach a script can be called directly by java, it only has to have proper permissions and have in the first line the reference to its interpreter Commented Jul 25, 2013 at 21:18

3 Answers 3

1

Verify two things:

  • If you have modified the perl script, make sure it has #!/bin/perl in the first line, same for your shell script, it must have #!/bin/sh or #!/bin/bash if you are specificaly using bash.

  • Your moved files must have executable permissions, change them with something like .chmod 755 myFile.

Sign up to request clarification or add additional context in comments.

1 Comment

I did make sure of that. I have methods that change the permissions of the files by calling chmod 777. It works perfectly fine. Also, the perl script has the line #!/usr/bin/perl and my shell has #!/bin/bash
1

The way you state the problem seems unsolvable. Since this used to work apparently one of two things changed: Either your java execution environment or your OS environment (this is why file permissions come to mind first).

Since you can execute the scripts manually the most probable cause seems to be that java cannot execute the scripts for some reason.

Please add the code below to your java program and check what is the exit code returned by the OS.

System.out.println("Waiting for process to finish...");
process.waitFor(); // wait until the process finishes
int exitCode = process.exitValue();
System.out.println("Process exit code: " + exitCode); 

Edit: After the clarifications provided in the comments the most probable scenario is that command line arguments to your script are being passed incorrectly by Java. It is relatively easy to test that: Just add as a first line to your shell script command echo $1 $2 $3 for as many arguments as it takes. This way you will identify if arguments are being passed correctly. If not, then the problem lies on Java side and we should use the String[] version of exec(). I am used to Processbuilder so I will use that in my example (please use the code below after you have performed the test above so we know what arguments are missing):

String shellScript = "/some/path/runPerlScript.sh";
String perlScript = "/some/path/perlscript.pl";

// similar to using exec() version with String[]
ProcessBuilder pb = new ProcessBuilder(shellScript , perlScript); 

// print what the process will see as current directory
File workDir = pb.directory();
System.out.println("Working directoy:" + workDir.getAbsolutePath());

// print the environment variables visible to the process
Map<String, String> env = pb.environment(); 
System.out.println("Environment available to shell script:\n" + env);

// set the working directory if needed depending on the output of the workDir above
pb.directory(new File("/some/path")); 
Process p = pb.start();

// add the lines from the previous snipet here that waits until the process is done

5 Comments

The Exit Value is 0. Doesn't that indicate normal termination?
@JeremyFisher yes this indicates a succesful execution. Please check a) Does your script produce any output to the console if run as stand-alone? I mean do you see anything between the above lines "Waiting for process to finish..." and "Process exit code: "? If not, please add an echo statement in it as the first command. b) if you move the script to its original location is it still executed succesfully from java as it used to be the case?
I redirected the output from my shell script to my console. The strange thing is, the echo statements from my shell script are printed to the console. Also, a print statement from the Perl script is printed to the console as well. This would indicate that Java is calling the shell script which is calling the perl script, but the perl script doesn't seem to find any arguments. Also, it is now producing the error code 255.
Also, if I call the shell script from the terminal, regardless of which directory it is in, it is still able to run perfectly well. Something is clearly not functioning between Java and Unix.
@JeremyFisher please check my edit in the answer. I suggest for all your tests to use the terminal from now on (java program included)
1

I took a look at some Javadocs and came up with this solution for my problem. Don't know exactly why it works, but it works!

    ProcessBuilder builder = new ProcessBuilder(p1);

        builder.directory(dirFile);
        Process process = builder.start();
        System.out.println("Process working directory: "+builder.directory().getAbsolutePath());
        InputStream is = process.getInputStream();
        InputStreamReader reader = new InputStreamReader(is);
        Scanner scan = new Scanner(reader);


        while(scan.hasNextLine()){
            System.out.println(scan.nextLine());
        }

Basically, I just specified the working directory of the ProcessBuilder. I also passed a String[] to ProcessBuilder instead of a string, and I specified my shell in my string array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.