jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,252 @@
+/*
+ * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.jdi;
+
+import com.sun.tools.jdi.*;
+import com.sun.jdi.connect.*;
+import com.sun.jdi.connect.spi.*;
+import com.sun.jdi.VirtualMachine;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Random;
+import java.io.IOException;
+import java.io.File;
+
+public class SunCommandLineLauncher extends AbstractLauncher implements LaunchingConnector {
+
+    static private final String ARG_HOME = "home";
+    static private final String ARG_OPTIONS = "options";
+    static private final String ARG_MAIN = "main";
+    static private final String ARG_INIT_SUSPEND = "suspend";
+    static private final String ARG_QUOTE = "quote";
+    static private final String ARG_VM_EXEC = "vmexec";
+
+    TransportService transportService;
+    Transport transport;
+    boolean usingSharedMemory = false;
+
+    TransportService transportService() {
+        return transportService;
+    }
+
+    public Transport transport() {
+        return transport;
+    }
+
+    public SunCommandLineLauncher() {
+        super();
+
+        /**
+         * By default this connector uses either the shared memory
+         * transport or the socket transport
+         */
+        try {
+            Class c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService");
+            transportService = (TransportService)c.newInstance();
+            transport = new Transport() {
+                public String name() {
+                    return "dt_shmem";
+                }
+            };
+            usingSharedMemory = true;
+        } catch (ClassNotFoundException x) {
+        } catch (UnsatisfiedLinkError x) {
+        } catch (InstantiationException x) {
+        } catch (IllegalAccessException x) {
+        };
+        if (transportService == null) {
+            transportService = new SocketTransportService();
+            transport = new Transport() {
+                public String name() {
+                    return "dt_socket";
+                }
+            };
+        }
+
+        addStringArgument(
+                ARG_HOME,
+                getString("sun.home.label"),
+                getString("sun.home"),
+                System.getProperty("java.home"),
+                false);
+        addStringArgument(
+                ARG_OPTIONS,
+                getString("sun.options.label"),
+                getString("sun.options"),
+                "",
+                false);
+        addStringArgument(
+                ARG_MAIN,
+                getString("sun.main.label"),
+                getString("sun.main"),
+                "",
+                true);
+
+        addBooleanArgument(
+                ARG_INIT_SUSPEND,
+                getString("sun.init_suspend.label"),
+                getString("sun.init_suspend"),
+                true,
+                false);
+
+        addStringArgument(
+                ARG_QUOTE,
+                getString("sun.quote.label"),
+                getString("sun.quote"),
+                "\"",
+                true);
+        addStringArgument(
+                ARG_VM_EXEC,
+                getString("sun.vm_exec.label"),
+                getString("sun.vm_exec"),
+                "java",
+                true);
+    }
+
+    static boolean hasWhitespace(String string) {
+        int length = string.length();
+        for (int i = 0; i < length; i++) {
+            if (Character.isWhitespace(string.charAt(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public VirtualMachine
+        launch(Map<String,? extends Connector.Argument> arguments)
+        throws IOException, IllegalConnectorArgumentsException,
+               VMStartException
+    {
+        VirtualMachine vm;
+
+        String home = argument(ARG_HOME, arguments).value();
+        String options = argument(ARG_OPTIONS, arguments).value();
+        String mainClassAndArgs = argument(ARG_MAIN, arguments).value();
+        boolean wait = ((BooleanArgumentImpl)argument(ARG_INIT_SUSPEND,
+                                                  arguments)).booleanValue();
+        String quote = argument(ARG_QUOTE, arguments).value();
+        String exe = argument(ARG_VM_EXEC, arguments).value();
+        String exePath = null;
+
+        if (quote.length() > 1) {
+            throw new IllegalConnectorArgumentsException("Invalid length",
+                                                         ARG_QUOTE);
+        }
+
+        if ((options.indexOf("-Djava.compiler=") != -1) &&
+            (options.toLowerCase().indexOf("-djava.compiler=none") == -1)) {
+            throw new IllegalConnectorArgumentsException("Cannot debug with a JIT compiler",
+                                                         ARG_OPTIONS);
+        }
+
+        /*
+         * Start listening.
+         * If we're using the shared memory transport then we pick a
+         * random address rather than using the (fixed) default.
+         * Random() uses System.currentTimeMillis() as the seed
+         * which can be a problem on windows (many calls to
+         * currentTimeMillis can return the same value), so
+         * we do a few retries if we get an IOException (we
+         * assume the IOException is the filename is already in use.)
+         */
+        TransportService.ListenKey listenKey;
+        if (usingSharedMemory) {
+            Random rr = new Random();
+            int failCount = 0;
+            while(true) {
+                try {
+                    String address = "javadebug" +
+                        String.valueOf(rr.nextInt(100000));
+                    listenKey = transportService().startListening(address);
+                    break;
+                } catch (IOException ioe) {
+                    if (++failCount > 5) {
+                        throw ioe;
+                    }
+                }
+            }
+        } else {
+            listenKey = transportService().startListening();
+        }
+        String address = listenKey.address();
+
+        try {
+            if (home.length() > 0) {
+                /*
+                 * A wrinkle in the environment:
+                 * 64-bit executables are stored under $JAVA_HOME/bin/os_arch
+                 * 32-bit executables are stored under $JAVA_HOME/bin
+                 */
+                String os_arch = System.getProperty("os.arch");
+                if ("SunOS".equals(System.getProperty("os.name")) &&
+                   ("sparcv9".equals(os_arch) || "amd64".equals(os_arch))) {
+                    exePath = home + File.separator + "bin" + File.separator +
+                        os_arch + File.separator + exe;
+                } else {
+                    exePath = home + File.separator + "bin" + File.separator + exe;
+                }
+            } else {
+                exePath = exe;
+            }
+            // Quote only if necessary in case the quote arg value is bogus
+            if (hasWhitespace(exe)) {
+                exePath = quote + exePath + quote;
+            }
+
+            String xrun = "transport=" + transport().name() +
+                          ",address=" + address +
+                          ",suspend=" + (wait? 'y' : 'n');
+            // Quote only if necessary in case the quote arg value is bogus
+            if (hasWhitespace(xrun)) {
+                xrun = quote + xrun + quote;
+            }
+
+            String command = exePath + ' ' +
+                             options + ' ' +
+                             "-Xdebug " +
+                             "-Xrunjdwp:" + xrun + ' ' +
+                             mainClassAndArgs;
+
+            // System.err.println("Command: \"" + command + '"');
+            vm = launch(tokenizeCommand(command, quote.charAt(0)), address, listenKey,
+                        transportService());
+        } finally {
+            transportService().stopListening(listenKey);
+        }
+
+        return vm;
+    }
+
+    public String name() {
+        return "com.sun.jdi.CommandLineLaunch";
+    }
+
+    public String description() {
+        return getString("sun.description");
+
+    }
+}