Browse Source

support both same- and other-vm runs using new using new LangUtil API's for running processes

tags/V1_1_0_RC2
wisberg 21 years ago
parent
commit
f8c0574fd9
1 changed files with 139 additions and 31 deletions
  1. 139
    31
      ajde/src/org/aspectj/ajde/Ajde.java

+ 139
- 31
ajde/src/org/aspectj/ajde/Ajde.java View File

@@ -14,10 +14,6 @@

package org.aspectj.ajde;

import java.io.File;
import java.io.PrintStream;
import java.util.List;

import org.aspectj.ajde.internal.AspectJBuildManager;
import org.aspectj.ajde.internal.LstBuildConfigManager;
import org.aspectj.ajde.ui.EditorManager;
@@ -30,6 +26,10 @@ import org.aspectj.bridge.Version;
import org.aspectj.util.LangUtil;
import org.aspectj.util.Reflection;

import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

/**
* Singleton class responsible for AJDE initialization, and the main point of access to
* Ajde functionality.
@@ -41,33 +41,7 @@ public class Ajde {
private static final Ajde INSTANCE = new Ajde();
private static final String NOT_INITIALIZED_MESSAGE = "Ajde is not initialized.";
private static boolean isInitialized = false;

/**
* Utility to run the project main class in the same VM
* using a class loader populated with the classpath
* and output path or jar.
* @param project the ProjectPropertiesAdapter specifying the
* main class, classpath, and executable arguments.
*/
public static void runInSameVM(ProjectPropertiesAdapter project) {
String mainClass = "<none>";
try {
mainClass = project.getClassToExecute();
if (LangUtil.isEmpty(mainClass)) {
Ajde.getDefault().getErrorHandler().handleWarning("No main class specified");
}
String classpath = project.getOutputPath();
if (LangUtil.isEmpty(classpath)) {
classpath = project.getOutJar();
}
classpath += File.pathSeparator + project.getClasspath();
String[] args = LangUtil.split(project.getExecutionArgs());
Reflection.runMainInSameVM(classpath, mainClass, args);
} catch(Throwable e) {
Ajde.getDefault().getErrorHandler().handleError("Error running " + mainClass, e);
}
}

private BuildManager buildManager;
private EditorManager editorManager;
private StructureViewManager structureViewManager;
@@ -206,6 +180,101 @@ public class Ajde {
}
}

/**
* Utility to run the project main class from the project
* properties in the same VM
* using a class loader populated with the classpath
* and output path or jar.
* Errors are logged to the ErrorHandler.
* @param project the ProjectPropertiesAdapter specifying the
* main class, classpath, and executable arguments.
* @return Thread running with process, or null if unable to start
*/
public Thread runInSameVM() {
final RunProperties props
= new RunProperties(getProjectProperties(), getErrorHandler());
if (!props.valid) {
return null; // error already handled
}
Runnable runner = new Runnable() {
public void run() {
try {
Reflection.runMainInSameVM(
props.classpath,
props.mainClass,
props.args);
} catch(Throwable e) {
Ajde.getDefault().getErrorHandler().handleError("Error running " + props.mainClass, e);
}
}
};
Thread result = new Thread(runner, props.mainClass);
result.start();
return result;
}

/**
* Utility to run the project main class from the project
* properties in a new VM.
* Errors are logged to the ErrorHandler.
* @return LangUtil.ProcessController running with process,
* or null if unable to start
*/
public LangUtil.ProcessController runInNewVM() {
final RunProperties props
= new RunProperties(getProjectProperties(), getErrorHandler());
if (!props.valid) {
return null; // error already handled
}
// setup to run asynchronously, pipe streams through, and report errors
final StringBuffer command = new StringBuffer();
LangUtil.ProcessController controller
= new LangUtil.ProcessController() {
protected void doCompleting(Throwable thrown, int result) {
LangUtil.ProcessController.Thrown any = getThrown();
if (!any.thrown && (null == thrown) && (0 == result)) {
return; // no errors
}
// handle errors
String context = props.mainClass
+ " command \""
+ command
+ "\"";
if (null != thrown) {
String m = "Exception running " + context;
getErrorHandler().handleError(m, thrown);
} else if (0 != result) {
String m = "Result of running " + context;
getErrorHandler().handleError(m + ": " + result);
}
if (null != any.fromInPipe) {
String m = "Error processing input pipe for " + context;
getErrorHandler().handleError(m, any.fromInPipe);
}
if (null != any.fromOutPipe) {
String m = "Error processing output pipe for " + context;
getErrorHandler().handleError(m, any.fromOutPipe);
}
if (null != any.fromErrPipe) {
String m = "Error processing error pipe for " + context;
getErrorHandler().handleError(m, any.fromErrPipe);
}
}
};
controller = LangUtil.makeProcess(
controller,
props.classpath,
props.mainClass,
props.args);
command.append(Arrays.asList(controller.getCommand()).toString());

// now run the process
controller.start();
return controller;
}

private final BuildConfigListener STRUCTURE_UPDATE_CONFIG_LISTENER = new BuildConfigListener() {
public void currConfigChanged(String configFilePath) {
if (configFilePath != null) Ajde.getDefault().getStructureModelManager().readStructureModel(configFilePath);
@@ -247,6 +316,45 @@ public class Ajde {
this.errorHandler = errorHandler;
}

/** struct class to interpret project properties */
private static class RunProperties {
final String mainClass;
final String classpath;
final String[] args;
final boolean valid;
RunProperties(
ProjectPropertiesAdapter project,
ErrorHandler handler) {
// XXX really run arbitrary handler in constructor? hmm.
LangUtil.throwIaxIfNull(project, "project");
LangUtil.throwIaxIfNull(handler, "handler");
String mainClass = null;
String classpath = null;
String[] args = null;
boolean valid = false;
mainClass = project.getClassToExecute();
if (LangUtil.isEmpty(mainClass)) {
handler.handleWarning("No main class specified");
} else {
classpath = LangUtil.makeClasspath(
project.getBootClasspath(),
project.getClasspath(),
project.getOutputPath(),
project.getOutJar());
if (LangUtil.isEmpty(classpath)) {
handler.handleWarning("No classpath specified");
} else {
args = LangUtil.split(project.getExecutionArgs());
valid = true;
}
}
this.mainClass = mainClass;
this.classpath = classpath;
this.args = args;
this.valid = valid;
}
}
}



Loading…
Cancel
Save