📄 emulatorrunner.java
字号:
/**
* Copyright (c) 2003-2005 Craig Setera
* All Rights Reserved.
* Licensed under the Eclipse Public License - v 1.0
* For more information see http://www.eclipse.org/legal/epl-v10.html
*/
package eclipseme.core.internal.launching;
import java.io.File;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdi.Bootstrap;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.launching.AbstractVMRunner;
import org.eclipse.jdt.launching.ExecutionArguments;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.SocketUtil;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
import com.sun.jdi.connect.ListeningConnector;
import eclipseme.core.EclipseMECoreStrings;
import eclipseme.core.IEclipseMECoreConstants;
import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.utils.Utils;
import eclipseme.core.model.IMidletSuiteProject;
import eclipseme.core.model.LaunchEnvironment;
import eclipseme.core.model.device.IDevice;
import eclipseme.core.model.device.IDevice2;
/**
* A VMRunner implementation that debugs against a wireless
* toolkit emulator. Places the standard VM debug arguments
* as program arguments when in debug mode. Otherwise, does
* not mess with that when not in debug mode.
* <p />
* Copyright (c) 2003-2005 Craig Setera<br>
* All Rights Reserved.<br>
* Licensed under the Eclipse Public License - v 1.0<p/>
* <br>
* $Revision: 1.8 $
* <br>
* $Date: 2006/02/11 21:26:57 $
* <br>
* @author Craig Setera
*/
public class EmulatorRunner extends AbstractVMRunner {
/**
* Used to attach to a VM in a seperate thread, to allow for cancellation
* and detect that the associated System process died before the connect
* occurred.
*/
class ConnectRunnable implements Runnable {
private VirtualMachine fVirtualMachine = null;
private ListeningConnector fConnector = null;
private Map fConnectionMap = null;
private Exception fException = null;
/**
* Constructs a runnable to connect to a VM via the given connector
* with the given connection arguments.
*
* @param connector
* @param map
*/
public ConnectRunnable(ListeningConnector connector, Map map) {
fConnector = connector;
fConnectionMap = map;
}
/**
* Thread entrypoint.
* @see java.lang.Runnable#run()
*/
public void run() {
try {
fVirtualMachine = fConnector.accept(fConnectionMap);
} catch (IOException e) {
fException = e;
} catch (IllegalConnectorArgumentsException e) {
fException = e;
}
}
/**
* Returns the VM that was attached to, or <code>null</code> if none.
*
* @return the VM that was attached to, or <code>null</code> if none
*/
public VirtualMachine getVirtualMachine() {
return fVirtualMachine;
}
/**
* Returns any exception that occurred while attaching, or <code>null</code>.
*
* @return IOException or IllegalConnectorArgumentsException
*/
public Exception getException() {
return fException;
}
}
/**
* Render the debug target string.
*
* @param classToRun
* @param host
* @return
*/
private static String renderDebugTarget(String classToRun, int host) {
return EclipseMECoreStrings.getString(
"debugvmrunner.debug_target_string",
new String[] { classToRun, String.valueOf(host) });
}
/**
* Render the process label string.
*
* @param commandLine
* @return
*/
public static String renderProcessLabel(String[] commandLine) {
String timestamp =
DateFormat.getInstance().format(
new Date(System.currentTimeMillis()));
return EclipseMECoreStrings.getString(
"debugvmrunner.process_label_string",
new String[] { commandLine[0], timestamp });
}
/**
* Render the command line string.
*
* @param commandLine
* @return
*/
private static String renderCommandLine(String[] commandLine) {
StringBuffer buf = new StringBuffer();
if (commandLine.length > 1) {
for (int i = 0; i < commandLine.length; i++) {
if (i > 0) buf.append(' ');
buf.append(commandLine[i]);
}
}
return buf.toString();
}
private IMidletSuiteProject suite;
private IDevice device;
private boolean debugMode;
/**
* Construct an VM runner instance for an executable emulator.
*
* @param emulator
*/
public EmulatorRunner(IMidletSuiteProject suite, IDevice device, String mode)
{
this.suite = suite;
this.device = device;
debugMode = ILaunchManager.DEBUG_MODE.equals(mode);
}
/**
* @see org.eclipse.jdt.launching.IVMRunner#run(org.eclipse.jdt.launching.VMRunnerConfiguration, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
*/
public void run(
VMRunnerConfiguration vmRunnerConfig,
ILaunchConfiguration launchConfig,
ILaunch launch,
IProgressMonitor monitor)
throws CoreException
{
if (debugMode) {
runInDebug(vmRunnerConfig, launchConfig, launch, monitor);
} else {
runWithoutDebug(vmRunnerConfig, launchConfig, launch, monitor);
}
}
/**
* Run the emulator with debugging.
*
* @param vmRunnerConfig
* @param launchConfig
* @param launch
* @param monitor
* @throws CoreException
*/
public void runInDebug(
VMRunnerConfiguration vmRunnerConfig,
ILaunchConfiguration launchConfig,
ILaunch launch,
IProgressMonitor monitor)
throws CoreException
{
if (monitor == null) {
monitor = new NullProgressMonitor();
}
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
subMonitor.beginTask(EclipseMECoreStrings.getString("debugvmrunner.launching_vm"), 4);
subMonitor.subTask(EclipseMECoreStrings.getString("debugvmrunner.finding_free_socket"));
int port = SocketUtil.findFreePort();
if (port == -1) {
abort(
EclipseMECoreStrings.getString("debugvmrunner.no_free_socket"),
null, IJavaLaunchConfigurationConstants.ERR_NO_SOCKET_AVAILABLE);
}
subMonitor.worked(1);
// check for cancellation
if (monitor.isCanceled()) {
return;
}
subMonitor.subTask(EclipseMECoreStrings.getString("debugvmrunner.constructing_cmd_line"));
String[] cmdLine = getCommandLine(launchConfig, port, monitor);
Utils.dumpCommandLine(cmdLine);
// check for cancellation
if (monitor.isCanceled()) {
return;
}
subMonitor.worked(1);
subMonitor.subTask(EclipseMECoreStrings.getString("debugvmrunner.starting_VM"));
Connector connector = getConnector();
if (connector == null) {
abort(
EclipseMECoreStrings.getString("debugvmrunner.no_connector"),
null,
IJavaLaunchConfigurationConstants.ERR_CONNECTOR_NOT_AVAILABLE);
}
Map map = connector.defaultArguments();
specifyArguments(map, port);
Process p = null;
try {
try {
// check for cancellation
if (monitor.isCanceled()) {
return;
}
if (!device.isDebugServer()) {
((ListeningConnector) connector).startListening(map);
}
File workingDir = getWorkingDir(vmRunnerConfig);
p = exec(cmdLine, workingDir);
if (p == null) {
return;
}
// check for cancellation
if (monitor.isCanceled()) {
p.destroy();
return;
}
IProcess process = DebugPlugin.newProcess(
launch, p,
renderProcessLabel(cmdLine),
getDefaultProcessMap());
process.setAttribute(
IProcess.ATTR_CMDLINE,
renderCommandLine(cmdLine));
subMonitor.worked(1);
subMonitor.subTask(
EclipseMECoreStrings.getString("debugvmrunner.establishing_debug_conn"));
// If the emulator debugger acts as a remote server,
// delay a bit to give the emulator a chance to start
// up.
if (device.isDebugServer()) {
Preferences preferences =
EclipseMECorePlugin.getDefault().getPluginPreferences();
int milliDelay = preferences.getInt(IEclipseMECoreConstants.PREF_RMTDBG_DELAY);
try {
Thread.sleep(milliDelay);
} catch (InterruptedException e) {}
}
VirtualMachine vm =
createVirtualMachine(connector, map, p, process, monitor);
JDIDebugModel.newDebugTarget(
launch, vm,
renderDebugTarget(vmRunnerConfig.getClassToLaunch(), port),
process, true, false);
subMonitor.worked(1);
subMonitor.done();
return;
} finally {
if (!device.isDebugServer()) {
((ListeningConnector) connector).stopListening(map);
}
}
} catch (IOException e) {
abort(
EclipseMECoreStrings.getString("debugvmrunner.couldnt_connect_to_vm"),
e, IJavaLaunchConfigurationConstants.ERR_CONNECTION_FAILED);
} catch (IllegalConnectorArgumentsException e) {
abort(
EclipseMECoreStrings.getString("debugvmrunner.couldnt_connect_to_vm"),
e, IJavaLaunchConfigurationConstants.ERR_CONNECTION_FAILED);
}
if (p != null) {
p.destroy();
}
}
/**
* Create a new VirtualMachine instances for the specified
* Connector and associated information.
*
* @param connector
* @param map
* @param p
* @param process
* @param monitor
* @return
* @throws IOException
* @throws IllegalConnectorArgumentsException
* @throws CoreException
*/
private VirtualMachine createVirtualMachine(
Connector connector, Map map,
Process p, IProcess process,
IProgressMonitor monitor)
throws IOException,
IllegalConnectorArgumentsException,
CoreException
{
VirtualMachine vm = (device.isDebugServer()) ?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -