How to run ant from an Eclipse plugin, send output to an Eclipse console, and capture the build result (success/failure)?
ant, console, eclipse
Solution
Edit 05/16/2016 @Lii alerted me to the fact that any output between the `ILaunchConfigurationWorkingCopy#launch` call and when the `IStreamListener` is appended will be lost. He made a contribution to this answer here.
Original Answer I realize this is an old post, but I was able to do exactly what you want in one of my plugins. If it doesn't help you at this point, maybe it will help someone else. I originally did this in 3.2, but it has been updated for 3.6 API changes...
// show the console
final IWorkbenchPage activePage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage();
activePage.showView(IConsoleConstants.ID_CONSOLE_VIEW);
// let launch manager handle ant script so output is directed to Console view
final ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = manager.getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
final ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, [*** GIVE YOUR LAUNCHER A NAME ***]);
workingCopy.setAttribute(ILaunchManager.ATTR_PRIVATE, true);
workingCopy.setAttribute(IExternalToolConstants.ATTR_LOCATION, [*** PATH TO ANT SCRIPT HERE ***]);
final ILaunch launch = workingCopy.launch(ILaunchManager.RUN_MODE, null);
// make sure the build doesnt fail
final boolean[] buildSucceeded = new boolean[] { true };
((AntProcess) launch.getProcesses()[0]).getStreamsProxy()
.getErrorStreamMonitor()
.addListener(new IStreamListener() {
@Override
public void streamAppended(String text, IStreamMonitor monitor) {
if (text.indexOf("BUILD FAILED") > -1) {
buildSucceeded[0] = false;
}
}
});
// wait for the launch (ant build) to complete
manager.addLaunchListener(new ILaunchesListener2() {
public void launchesTerminated(ILaunch[] launches) {
boolean patchSuccess = false;
try {
if (!buildSucceeded[0]) {
throw new Exception("Build FAILED!");
}
for (int i = 0; i < launches.length; i++) {
if (launches[i].equals(launch)
&& buildSucceeded[0]
&& !((IProgressMonitor) launches[i].getProcesses()[0]).isCanceled()) {
[*** DO YOUR THING... ***]
break;
}
}
} catch (Exception e) {
[*** DO YOUR THING... ***]
} finally {
// get rid of this listener
manager.removeLaunchListener(this);
[*** DO YOUR THING... ***]
}
}
public void launchesAdded(ILaunch[] launches) {
}
public void launchesChanged(ILaunch[] launches) {
}
public void launchesRemoved(ILaunch[] launches) {
}
});
Problem
From within an Eclipse plugin, I'd like to run an Ant build script. I also want to display the Ant output to the user, by displaying it in an Eclipse console. Finally, I also want to wait for the Ant build to be finished, and capture the result: did the build succeed or fail? I found three ways to run an Ant script from eclipse: - Instantiate an `org.eclipse.ant.core.AntRunner`, call some setters and call `run()` or `run(IProgressMonitor)`. The result is either normal termination (indicating success), or a CoreException with an `IStatus` containing a `BuildException` (indicating failure), or else something else went wrong. However, I don't see the Ant output anywhere. - Instantiate an `org.eclipse.ant.core.AntRunner` and call `run(Object)`, passing a `String[]` containing the command line arguments. The result is either normal termination (indication success), or an `InvocationTargetException` (indicating failure), or else something else went wrong. The Ant output is sent to Eclipse's stdout, it seems; it is not visible in Eclipse itself. - Call `DebugPlugin.getDefault().getLaunchManager()`, then on that call `getLaunchConfigurationType(IAntLaunchConfigurationConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE)`, then on that set attribute `"org.eclipse.ui.externaltools.ATTR_LOCATION"` to the build file name (and attribute `DebugPlugin.ATTR_CAPTURE_OUTPUT` to true) and finally call `launch()`. The Ant output is shown in an Eclipse console, but I have no idea how to capture the build result (success/failure) in my code. Or how to wait for termination of the launch, even. Is there any way to have both console output and capture the result?