jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package com.sun.tools.jdi;
       
    27 
       
    28 import com.sun.tools.jdi.*;
       
    29 import com.sun.jdi.connect.*;
       
    30 import com.sun.jdi.connect.spi.*;
       
    31 import com.sun.jdi.VirtualMachine;
       
    32 import java.util.Map;
       
    33 import java.util.HashMap;
       
    34 import java.util.Random;
       
    35 import java.io.IOException;
       
    36 import java.io.File;
       
    37 
       
    38 public class SunCommandLineLauncher extends AbstractLauncher implements LaunchingConnector {
       
    39 
       
    40     static private final String ARG_HOME = "home";
       
    41     static private final String ARG_OPTIONS = "options";
       
    42     static private final String ARG_MAIN = "main";
       
    43     static private final String ARG_INIT_SUSPEND = "suspend";
       
    44     static private final String ARG_QUOTE = "quote";
       
    45     static private final String ARG_VM_EXEC = "vmexec";
       
    46 
       
    47     TransportService transportService;
       
    48     Transport transport;
       
    49     boolean usingSharedMemory = false;
       
    50 
       
    51     TransportService transportService() {
       
    52         return transportService;
       
    53     }
       
    54 
       
    55     public Transport transport() {
       
    56         return transport;
       
    57     }
       
    58 
       
    59     public SunCommandLineLauncher() {
       
    60         super();
       
    61 
       
    62         /**
       
    63          * By default this connector uses either the shared memory
       
    64          * transport or the socket transport
       
    65          */
       
    66         try {
       
    67             Class c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService");
       
    68             transportService = (TransportService)c.newInstance();
       
    69             transport = new Transport() {
       
    70                 public String name() {
       
    71                     return "dt_shmem";
       
    72                 }
       
    73             };
       
    74             usingSharedMemory = true;
       
    75         } catch (ClassNotFoundException x) {
       
    76         } catch (UnsatisfiedLinkError x) {
       
    77         } catch (InstantiationException x) {
       
    78         } catch (IllegalAccessException x) {
       
    79         };
       
    80         if (transportService == null) {
       
    81             transportService = new SocketTransportService();
       
    82             transport = new Transport() {
       
    83                 public String name() {
       
    84                     return "dt_socket";
       
    85                 }
       
    86             };
       
    87         }
       
    88 
       
    89         addStringArgument(
       
    90                 ARG_HOME,
       
    91                 getString("sun.home.label"),
       
    92                 getString("sun.home"),
       
    93                 System.getProperty("java.home"),
       
    94                 false);
       
    95         addStringArgument(
       
    96                 ARG_OPTIONS,
       
    97                 getString("sun.options.label"),
       
    98                 getString("sun.options"),
       
    99                 "",
       
   100                 false);
       
   101         addStringArgument(
       
   102                 ARG_MAIN,
       
   103                 getString("sun.main.label"),
       
   104                 getString("sun.main"),
       
   105                 "",
       
   106                 true);
       
   107 
       
   108         addBooleanArgument(
       
   109                 ARG_INIT_SUSPEND,
       
   110                 getString("sun.init_suspend.label"),
       
   111                 getString("sun.init_suspend"),
       
   112                 true,
       
   113                 false);
       
   114 
       
   115         addStringArgument(
       
   116                 ARG_QUOTE,
       
   117                 getString("sun.quote.label"),
       
   118                 getString("sun.quote"),
       
   119                 "\"",
       
   120                 true);
       
   121         addStringArgument(
       
   122                 ARG_VM_EXEC,
       
   123                 getString("sun.vm_exec.label"),
       
   124                 getString("sun.vm_exec"),
       
   125                 "java",
       
   126                 true);
       
   127     }
       
   128 
       
   129     static boolean hasWhitespace(String string) {
       
   130         int length = string.length();
       
   131         for (int i = 0; i < length; i++) {
       
   132             if (Character.isWhitespace(string.charAt(i))) {
       
   133                 return true;
       
   134             }
       
   135         }
       
   136         return false;
       
   137     }
       
   138 
       
   139     public VirtualMachine
       
   140         launch(Map<String,? extends Connector.Argument> arguments)
       
   141         throws IOException, IllegalConnectorArgumentsException,
       
   142                VMStartException
       
   143     {
       
   144         VirtualMachine vm;
       
   145 
       
   146         String home = argument(ARG_HOME, arguments).value();
       
   147         String options = argument(ARG_OPTIONS, arguments).value();
       
   148         String mainClassAndArgs = argument(ARG_MAIN, arguments).value();
       
   149         boolean wait = ((BooleanArgumentImpl)argument(ARG_INIT_SUSPEND,
       
   150                                                   arguments)).booleanValue();
       
   151         String quote = argument(ARG_QUOTE, arguments).value();
       
   152         String exe = argument(ARG_VM_EXEC, arguments).value();
       
   153         String exePath = null;
       
   154 
       
   155         if (quote.length() > 1) {
       
   156             throw new IllegalConnectorArgumentsException("Invalid length",
       
   157                                                          ARG_QUOTE);
       
   158         }
       
   159 
       
   160         if ((options.indexOf("-Djava.compiler=") != -1) &&
       
   161             (options.toLowerCase().indexOf("-djava.compiler=none") == -1)) {
       
   162             throw new IllegalConnectorArgumentsException("Cannot debug with a JIT compiler",
       
   163                                                          ARG_OPTIONS);
       
   164         }
       
   165 
       
   166         /*
       
   167          * Start listening.
       
   168          * If we're using the shared memory transport then we pick a
       
   169          * random address rather than using the (fixed) default.
       
   170          * Random() uses System.currentTimeMillis() as the seed
       
   171          * which can be a problem on windows (many calls to
       
   172          * currentTimeMillis can return the same value), so
       
   173          * we do a few retries if we get an IOException (we
       
   174          * assume the IOException is the filename is already in use.)
       
   175          */
       
   176         TransportService.ListenKey listenKey;
       
   177         if (usingSharedMemory) {
       
   178             Random rr = new Random();
       
   179             int failCount = 0;
       
   180             while(true) {
       
   181                 try {
       
   182                     String address = "javadebug" +
       
   183                         String.valueOf(rr.nextInt(100000));
       
   184                     listenKey = transportService().startListening(address);
       
   185                     break;
       
   186                 } catch (IOException ioe) {
       
   187                     if (++failCount > 5) {
       
   188                         throw ioe;
       
   189                     }
       
   190                 }
       
   191             }
       
   192         } else {
       
   193             listenKey = transportService().startListening();
       
   194         }
       
   195         String address = listenKey.address();
       
   196 
       
   197         try {
       
   198             if (home.length() > 0) {
       
   199                 /*
       
   200                  * A wrinkle in the environment:
       
   201                  * 64-bit executables are stored under $JAVA_HOME/bin/os_arch
       
   202                  * 32-bit executables are stored under $JAVA_HOME/bin
       
   203                  */
       
   204                 String os_arch = System.getProperty("os.arch");
       
   205                 if ("SunOS".equals(System.getProperty("os.name")) &&
       
   206                    ("sparcv9".equals(os_arch) || "amd64".equals(os_arch))) {
       
   207                     exePath = home + File.separator + "bin" + File.separator +
       
   208                         os_arch + File.separator + exe;
       
   209                 } else {
       
   210                     exePath = home + File.separator + "bin" + File.separator + exe;
       
   211                 }
       
   212             } else {
       
   213                 exePath = exe;
       
   214             }
       
   215             // Quote only if necessary in case the quote arg value is bogus
       
   216             if (hasWhitespace(exe)) {
       
   217                 exePath = quote + exePath + quote;
       
   218             }
       
   219 
       
   220             String xrun = "transport=" + transport().name() +
       
   221                           ",address=" + address +
       
   222                           ",suspend=" + (wait? 'y' : 'n');
       
   223             // Quote only if necessary in case the quote arg value is bogus
       
   224             if (hasWhitespace(xrun)) {
       
   225                 xrun = quote + xrun + quote;
       
   226             }
       
   227 
       
   228             String command = exePath + ' ' +
       
   229                              options + ' ' +
       
   230                              "-Xdebug " +
       
   231                              "-Xrunjdwp:" + xrun + ' ' +
       
   232                              mainClassAndArgs;
       
   233 
       
   234             // System.err.println("Command: \"" + command + '"');
       
   235             vm = launch(tokenizeCommand(command, quote.charAt(0)), address, listenKey,
       
   236                         transportService());
       
   237         } finally {
       
   238             transportService().stopListening(listenKey);
       
   239         }
       
   240 
       
   241         return vm;
       
   242     }
       
   243 
       
   244     public String name() {
       
   245         return "com.sun.jdi.CommandLineLaunch";
       
   246     }
       
   247 
       
   248     public String description() {
       
   249         return getString("sun.description");
       
   250 
       
   251     }
       
   252 }