1
votes

In a Java application, I want to execute a jar file with several options. To do this, I build a list of strings with all the command elements and I pass it to the Runtime.exec() method (It's really simple).

Here is the code with hard coded strings (The real code use variables of course):

List<String> cmd = new ArrayList<String>();
cmd.add("java");
cmd.add("-Dpython.path=\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\jython.jar\";\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\Lib\"");
cmd.add("-cp");
cmd.add("\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\..\\build\\jython-engine.jar\";\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\jython.jar\";\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\bin\\..\\plugins\\*\";\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\bin\\..\\kernel\\target\\qtaste-kernel-deploy.jar\";testapi\\target\\qtaste-testapi-deploy.jar");
cmd.add("org.python.util.jython");
cmd.add("Testbeds\\ControlScripts\\playback.py");
cmd.add("start");

int exitCode = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]), env, output);

On Windows 8, when I do that inside the JAVA application, I get an error : "Could not find or load main class With". If I execute directly the command in a console, it works. I think this error is due to spaces in some paths, but I don't understand how to do more than surround with quotes all the strings with spaces (like I've already done).

This code works perfectly on Linux when the root directory contains (or not) spaces. This code works also on Windows 8 when the root directory does not contain spaces.

Do you have an idea on how to fix this problem?

2

2 Answers

0
votes

Try to escape the spaces:

List<String> cmd = new ArrayList<String>();
cmd.add("java");
cmd.add("-Dpython.path=\"C:\\Users\\ange\\Documents\\QTaste\ With\ Spaces\\tools\\jython\\lib\\jython.jar\";\"C:\\Users\\ange\\Documents\\QTaste\ With\ Spaces\\tools\\jython\\lib\\Lib\"");
cmd.add("-cp");
cmd.add("\"C:\\Users\\ange\\Documents\\QTaste\ With\ Spaces\\tools\\jython\\lib\\..\\build\\jython-engine.jar\";\"C:\\Users\\ange\\Documents\\QTaste\ With\ Spaces\\tools\\jython\\lib\\jython.jar\";\"C:\\Users\\ange\\Documents\\QTaste\ With\ Spaces\\bin\\..\\plugins\\*\";\"C:\\Users\\ange\\Documents\\QTaste\ With\ Spaces\\bin\\..\\kernel\\target\\qtaste-kernel-deploy.jar\";testapi\\target\\qtaste-testapi-deploy.jar");
cmd.add("org.python.util.jython");
cmd.add("Testbeds\\ControlScripts\\playback.py");
cmd.add("start");

int exitCode = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]), env, output);

EDIT

Don't escape spaces, but put the full classpath between quotes.

The following code work for me, and if I try to write a wrong classPath the program prints the error given by java

public static void main(String[] args) throws InterruptedException, IOException {
    List<String> cmd = new ArrayList<String>();
    cmd.add("java");
    cmd.add("-Dpython.path=\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\jython.jar\";\"C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\Lib\"");
    cmd.add("-cp");
    cmd.add("\""
            + "C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\..\\build\\jython-engine.jar;"
            + "C:\\Users\\ange\\Documents\\QTaste With Spaces\\tools\\jython\\lib\\jython.jar;"
            + "C:\\Users\\ange\\Documents\\QTaste With Spaces\\bin\\..\\plugins\\*;"
            + "C:\\Users\\ange\\Documents\\QTaste With Spaces\\bin\\..\\kernel\\target\\qtaste-kernel-deploy.jar;"
            + "testapi\\target\\qtaste-testapi-deploy.jar;"
            + "\"");
    cmd.add("org.python.util.jython");
    cmd.add("Testbeds\\ControlScripts\\playback.py");
    cmd.add("start");

    System.out.println("START...");

    Process p = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]));

    final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
    new Thread(new Runnable(){
        public void run() {
            String line;
            try {
                while ((line = in.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        };
    }).start();

    final BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
    new Thread(new Runnable(){
        public void run() {
            String line;
            try {
                while ((line = err.readLine()) != null) {
                    System.err.println(line);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        };
    }).start();

    int exitStatus = p.waitFor();
    System.out.println("exit status: " + exitStatus);
}
0
votes

I surrounded the -Dpython.path parameters by simple quote and it works...

public static void main(String[] args) throws InterruptedException, IOException {
        List<String> cmd = new ArrayList<String>();
//      String qtasteHome = "C:\\Users\\ange\\Documents\\QTaste With Spaces"; //RBA
//      String qtasteHome = "/home/dev/workspaces/qtaste"; // UBUNTU
        String qtasteHome = "D:\\Qtaste with spaces"; // Win 8.1
        cmd.add("java");
        cmd.add("-Dpython.path='" + qtasteHome + "\\tools\\jython\\lib\\jython.jar';'" + qtasteHome + "\\tools\\jython\\lib\\Lib'");
        cmd.add("-cp");
        cmd.add("\""
                + qtasteHome + "\\tools\\jython\\lib\\..\\build\\jython-engine.jar;"
                + qtasteHome + "\\tools\\jython\\lib\\jython.jar;"
                + qtasteHome + "\\bin\\..\\plugins\\*;"
                + qtasteHome + "\\bin\\..\\kernel\\target\\qtaste-kernel-deploy.jar;"
                + "testapi\\target\\qtaste-testapi-deploy.jar;"
            + "\"");
        cmd.add("org.python.util.jython");
        cmd.add("Testbeds\\ControlScripts\\playback.py");
        cmd.add("start");

        String command = "";
        System.out.println("command parts :");
        for ( String s : cmd)
        {
            System.out.println("\t" + s);
            command += " " + s;
        }

        System.out.println("\nCommand : \n-------\n" + command + "\n-------");

        System.out.println("START...");

        Process p = Runtime.getRuntime().exec(
                cmd.toArray(new String[cmd.size()]));

        final BufferedReader in = new BufferedReader(new InputStreamReader(
                p.getInputStream()));
        new Thread(new Runnable() {
            public void run() {
                String line;
                try {
                    while ((line = in.readLine()) != null) {
                        System.out.println(line);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            };
        }).start();

        final BufferedReader err = new BufferedReader(new InputStreamReader(
                p.getErrorStream()));
        new Thread(new Runnable() {
            public void run() {
                String line;
                try {
                    while ((line = err.readLine()) != null) {
                        System.err.println(line);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            };
        }).start();

        int exitStatus = p.waitFor();
        System.out.println("exit status: " + exitStatus);