/* * Copyright (c) 2000, 2001, 2002 Paul Kinnucan * * $Revision: 1.7 $ */ package jde.debugger.command; import jde.debugger.JDEException; import com.sun.jdi.connect.LaunchingConnector; import java.util.Map; import com.sun.jdi.connect.Connector; import java.util.Iterator; import com.sun.jdi.VirtualMachine; import java.io.IOException; import com.sun.jdi.connect.IllegalConnectorArgumentsException; import com.sun.jdi.connect.VMStartException; import jde.debugger.DebuggeeProcess; import jde.debugger.Jdebug; import jde.debugger.Debug; import jde.debugger.DebuggeeSIO; /** * Launches an application. *

* * Syntax: *

 * launch app_id [-use_executable javax] classname [args]
 * 
* * @author Paul Kinnucan * @version $Revision: 1.7 $ */ public class LaunchApplication extends DebugSessionCommand { /** * * @exception jde.debugger.JDEException */ public void doCommand() throws JDEException { // this is the connector that launches a debuggee vm String connectSpec = "com.sun.jdi.CommandLineLaunch"; // check if this kind of connector is, indeed, // available. if not, throw an exception. LaunchingConnector connector = (LaunchingConnector) getConnector(connectSpec); if (connector == null) throw new JDEException("No such connector is available: "+connectSpec); // first set up the argument map. a table that describes the // different keys should be in the public jpda documentation. // internally, it is at // http://jbug/jbug/doc/conninv.html Map argumentMap = connector.defaultArguments(); Connector.Argument mainArg = (Connector.Argument)argumentMap.get("main"); // compose the command line String commandLine = ""; String quote =((Connector.Argument)argumentMap.get("quote")).value(); // check if there are special launch options we need to process if (args.size() == 0) throw new JDEException("Insufficient arguments"); String executable = "java"; // be careful with the loop here.... while ((args.size() >0) && args.get(0).toString().startsWith("-")) { String origArg = args.remove(0).toString(); String arg = origArg.toLowerCase(); if (arg.equals("-vmexec")) { if (args.size() == 0) throw new JDEException("Missing argument to 'use_executable'"); executable = args.remove(0).toString(); Connector.Argument vmexecArg = (Connector.Argument)argumentMap.get("vmexec"); vmexecArg.setValue(executable); } else if (arg.equals("-home")) { if (args.size() == 0) throw new JDEException("Missing argument to 'home'"); String home = args.remove(0).toString(); Connector.Argument homeArg = (Connector.Argument) argumentMap.get("home"); homeArg.setValue(home); continue; } else { args.add(0, origArg); break; } } if (args.size() == 0) throw new JDEException("Missing arguments: no class specified?"); // take care of spaces too! so quote everything. Iterator iterator = args.iterator(); while(iterator.hasNext()) { // commandLine += quote + iterator.next() + quote + " "; String arg = (String)iterator.next(); if (arg.equalsIgnoreCase("-classic")) { Connector.Argument optionsArg = (Connector.Argument)argumentMap.get("options"); String options = optionsArg.value(); options = "-classic" + " " + options; optionsArg.setValue(options); jde.signal(procID, MESSAGE, "VM options: '" + options + "'"); } else commandLine += quote + arg + quote + " "; } mainArg.setValue(commandLine); // signal(DEBUG, "Command line: '"+executable+" "+commandLine+"'"); VirtualMachine vm = null; try { vm = connector.launch(argumentMap); jde.signal(procID, MESSAGE, "Launched VM " + vm.description()); } catch (IOException ex) { Debug.printIf(ex); throw new JDEException("Unable to launch: " + ex.toString().replace('\\','/')); } catch (IllegalConnectorArgumentsException ex) { throw new JDEException("Invalid or inconsistent connector arguments for connector '"+connector+"'"); } catch (VMStartException ex) { // dumpFailedAppStreams(ex.process()); throw new JDEException(ex.getMessage().toString().replace('\\','/')); } // note that new debuggee process might raise a jdeexception. DebuggeeProcess proc = new DebuggeeProcess(procID, vm); if (procRegistry.processExists(procID)) { proc.shutdown(); throw new JDEException("An application with the same ID exists."); } procRegistry.addProcess(procID, proc); DebuggeeSIO procSIO = proc.getSIO(); // Create a socket for connecting the application's standard I/O // to Emacs and a thread that waits for Emacs to connect to the socket. int port = procSIO.initConnect(cmdID); // Tell Emacs the number of the standard I/O socket. // jde.signalCommandResult(procID, cmdID, new Integer(port)); } public Object clone() {return new LaunchApplication();} } // LaunchApplication /* * $Log: LaunchApplication.java,v $ * Revision 1.7 2002/10/11 05:41:06 paulk * Fixed bug where the debuggee application launcher was downcasing the first vm command line argument. Thanks toEric W Brown for this fix. * * Revision 1.6 2001/05/24 02:50:06 paulk * Moved jde.signalCommandResult(...., * port) from LaunchApplication.java into the same thread that creates a * server SIO socket to make sure that Emacs connects to this socket after its * creation. Thanks to "Eugene Gavrilov" . * * Revision 1.5 2001/03/24 05:42:37 paulk * Updated to reflect reorganization of debugger code. * * Revision 1.4 2000/07/28 06:27:02 paulk * Committing all modified files. * * Revision 1.3 2000/03/03 07:45:05 paulk * Replaced backslashes with forward slashes in launch error messages. * * Revision 1.2 2000/01/31 12:41:45 paulk * * Continue converting commands from functional to OO implementation. * * Revision 1.1 2000/01/30 12:39:50 paulk * Defines command to launch debuggee application. * */ // End of LaunchApplication.java