1 /*
   2  * Copyright (c) 2003, 2004, Oracle and/or its affiliates. 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * A Simple LaunchingConnector used by unit test :-
  26  * test/com/sun/jdi/connect/spi/DebugUsingCustomConnector.java
  27  */
  28 import com.sun.jdi.VirtualMachine;
  29 import com.sun.jdi.Bootstrap;
  30 import com.sun.jdi.connect.Connector;
  31 import com.sun.jdi.connect.LaunchingConnector;
  32 import com.sun.jdi.connect.Transport;
  33 import com.sun.jdi.connect.IllegalConnectorArgumentsException;
  34 import com.sun.jdi.connect.VMStartException;
  35 import com.sun.jdi.connect.spi.TransportService;
  36 import com.sun.jdi.connect.spi.Connection;
  37 import java.io.IOException;
  38 import java.io.File;
  39 import java.util.Map;
  40 import java.util.HashMap;
  41 
  42 public class SimpleLaunchingConnector implements LaunchingConnector {
  43     TransportService ts;
  44     String ARG_NAME = "class";
  45 
  46     /*
  47      * Simple implementation of Connector.StringArgument
  48      */
  49     static class StringArgumentImpl implements Connector.StringArgument {
  50         String name;
  51         String label;
  52         String description;
  53         String value;
  54 
  55         StringArgumentImpl(String name, String label, String description, String value) {
  56             this.name = name;
  57             this.label = label;
  58             this.description = description;
  59             this.value = value;
  60         }
  61 
  62         public String name() {
  63             return name;
  64         }
  65 
  66         public String label() {
  67             return label;
  68         }
  69 
  70         public String description() {
  71             return description;
  72         }
  73 
  74         public String value() {
  75             return value;
  76         }
  77 
  78         public void setValue(String value) {
  79             this.value = value;
  80         }
  81 
  82         public boolean isValid(String value) {
  83             if (value.length() > 0) {
  84                 return true;
  85             }
  86             return false;
  87         }
  88 
  89         public boolean mustSpecify() {
  90             return true;
  91         }
  92     }
  93 
  94     public SimpleLaunchingConnector() {
  95         try {
  96             Class c = Class.forName("com.sun.tools.jdi.SocketTransportService");
  97             ts = (TransportService)c.newInstance();
  98         } catch (Exception x) {
  99             throw new Error(x);
 100         }
 101     }
 102 
 103     public String name() {
 104         return "SimpleLaunchingConnector";
 105     }
 106 
 107     public String description() {
 108         return "SimpleLaunchingConnector";
 109     }
 110 
 111     public Transport transport() {
 112         return new Transport() {
 113             public String name() {
 114                 return ts.name();
 115             }
 116         };
 117     }
 118 
 119     public Map defaultArguments() {
 120         HashMap map = new HashMap();
 121         map.put(ARG_NAME,
 122                 new StringArgumentImpl(ARG_NAME, "class name", "class name", ""));
 123         return map;
 124     }
 125 
 126     public VirtualMachine launch(Map<String, ? extends Connector.Argument> arguments) throws
 127                               IOException,
 128                               IllegalConnectorArgumentsException,
 129                               VMStartException {
 130 
 131         /*
 132          * Get the class name that we are to execute
 133          */
 134         String className = ((StringArgumentImpl)arguments.get(ARG_NAME)).value();
 135         if (className.length() == 0) {
 136             throw new IllegalConnectorArgumentsException("class name missing", ARG_NAME);
 137         }
 138 
 139         /*
 140          * Listen on an emperical port; launch the debuggee; wait for
 141          * for the debuggee to connect; stop listening;
 142          */
 143         TransportService.ListenKey key = ts.startListening();
 144 
 145         String exe = System.getProperty("java.home") + File.separator + "bin" +
 146             File.separator;
 147         String arch = System.getProperty("os.arch");
 148         String osname = System.getProperty("os.name");
 149         if (osname.equals("SunOS") && arch.equals("sparcv9")) {
 150             exe += "sparcv9/java";
 151         } else if (osname.equals("SunOS") && arch.equals("amd64")) {
 152             exe += "amd64/java";
 153         } else {
 154             exe += "java";
 155         }
 156         String cmd = exe + " -Xdebug -Xrunjdwp:transport=dt_socket,timeout=15000,address=" +
 157             key.address() +
 158             " -classpath " + System.getProperty("test.classes") +
 159             " " + className;
 160         Process process = Runtime.getRuntime().exec(cmd);
 161         Connection conn = ts.accept(key, 30*1000, 9*1000);
 162         ts.stopListening(key);
 163 
 164         /*
 165          * Debugee is connected - return the virtual machine mirror
 166          */
 167         return Bootstrap.virtualMachineManager().createVirtualMachine(conn);
 168     }
 169 }