SubprocessUtil.java revision 12657:6ef01bd40ce2
1156956Sume/*
2156956Sume * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
3156956Sume * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4156956Sume *
5156956Sume * This code is free software; you can redistribute it and/or modify it
6156956Sume * under the terms of the GNU General Public License version 2 only, as
7156956Sume * published by the Free Software Foundation.
8156956Sume *
9156956Sume * This code is distributed in the hope that it will be useful, but WITHOUT
10156956Sume * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11156956Sume * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12156956Sume * version 2 for more details (a copy is included in the LICENSE file that
13156956Sume * accompanied this code).
14156956Sume *
15156956Sume * You should have received a copy of the GNU General Public License version
16156956Sume * 2 along with this work; if not, write to the Free Software Foundation,
17156956Sume * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18156956Sume *
19156956Sume * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20236695Sdim * or visit www.oracle.com if you need additional information or have any
21156956Sume * questions.
22156956Sume */
23package org.graalvm.compiler.test;
24
25import java.io.File;
26import java.io.IOException;
27import java.nio.file.Files;
28import java.util.Arrays;
29import java.util.List;
30
31/**
32 * Utility methods for spawning a VM in a subprocess during unit tests.
33 */
34public final class SubprocessUtil {
35
36    private SubprocessUtil() {
37    }
38
39    /**
40     * Gets the command line for the current process.
41     *
42     * @return the command line arguments for the current process or {@code null} if they are not
43     *         available
44     */
45    public static List<String> getProcessCommandLine() {
46        String processArgsFile = System.getenv().get("MX_SUBPROCESS_COMMAND_FILE");
47        if (processArgsFile != null) {
48            try {
49                return Files.readAllLines(new File(processArgsFile).toPath());
50            } catch (IOException e) {
51            }
52        }
53        return null;
54    }
55
56    /**
57     * Gets the command line used to start the current Java VM, including all VM arguments, but not
58     * including the main class or any Java arguments. This can be used to spawn an identical VM,
59     * but running different Java code.
60     */
61    public static List<String> getVMCommandLine() {
62        List<String> args = getProcessCommandLine();
63        if (args == null) {
64            return null;
65        } else {
66            int index = findMainClassIndex(args);
67            return args.subList(0, index);
68        }
69    }
70
71    public static final List<String> JVM_OPTIONS_WITH_ONE_ARG = System.getProperty("java.specification.version").compareTo("1.9") < 0 ? //
72                    Arrays.asList("-cp", "-classpath") : //
73                    Arrays.asList("-cp", "-classpath", "-mp", "-modulepath", "-upgrademodulepath", "-addmods", "-m", "-limitmods");
74
75    private static int findMainClassIndex(List<String> commandLine) {
76        int i = 1; // Skip the java executable
77
78        while (i < commandLine.size()) {
79            String s = commandLine.get(i);
80            if (s.charAt(0) != '-') {
81                return i;
82            } else if (JVM_OPTIONS_WITH_ONE_ARG.contains(s)) {
83                i += 2;
84            } else {
85                i++;
86            }
87        }
88        throw new InternalError();
89    }
90
91}
92