简体   繁体   English

如何从Eclipse插件运行ant,将输出发送到Eclipse控制台,并捕获构建结果(成功/失败)?

[英]How to run ant from an Eclipse plugin, send output to an Eclipse console, and capture the build result (success/failure)?

From within an Eclipse plugin, I'd like to run an Ant build script. 在Eclipse插件中,我想运行一个Ant构建脚本。 I also want to display the Ant output to the user, by displaying it in an Eclipse console. 我还想通过在Eclipse控制台中显示Ant输出来向用户显示它。 Finally, I also want to wait for the Ant build to be finished, and capture the result: did the build succeed or fail? 最后,我还想等待Ant构建完成,并捕获结果:构建成功还是失败?

I found three ways to run an Ant script from eclipse: 我发现了三种从eclipse运行Ant脚本的方法:

  • Instantiate an org.eclipse.ant.core.AntRunner , call some setters and call run() or run(IProgressMonitor) . 实例化一个org.eclipse.ant.core.AntRunner ,调用一些setter并调用run()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. 其结果要么是正常终止(表示成功),或与一个CoreException IStatus含有BuildException (表示失败),否则别的东西出了问题。 However, I don't see the Ant output anywhere. 但是,我没有看到任何地方的Ant输出。
  • Instantiate an org.eclipse.ant.core.AntRunner and call run(Object) , passing a String[] containing the command line arguments. 实例化org.eclipse.ant.core.AntRunner并调用run(Object) ,传递包含命令行参数的String[] The result is either normal termination (indication success), or an InvocationTargetException (indicating failure), or else something else went wrong. 结果是正常终止(指示成功)或InvocationTargetException (指示失败),否则出现其他错误。 The Ant output is sent to Eclipse's stdout, it seems; 看来,Ant输出被发送到Eclipse的stdout; it is not visible in Eclipse itself. 它在Eclipse本身中不可见。
  • 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() . 调用DebugPlugin.getDefault().getLaunchManager() ,然后在该调用上调用getLaunchConfigurationType(IAntLaunchConfigurationConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE) ,然后在该set属性"org.eclipse.ui.externaltools.ATTR_LOCATION"上调用构建文件名(和属性DebugPlugin.ATTR_CAPTURE_OUTPUT到是的)最后调用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. Ant输出显示在Eclipse控制台中,但我不知道如何在代码中捕获构建结果(成功/失败)。 Or how to wait for termination of the launch, even. 或者甚至如何等待终止发射。

Is there any way to have both console output and capture the result? 有没有办法同时拥有控制台输出,并捕获结果呢?

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. 编辑 05/16/2016 @Lii提醒我, ILaunchConfigurationWorkingCopy#launch调用和附加IStreamListener之间的任何输出都将丢失。 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... 我最初在3.2中做过这个,但它已针对3.6 API更改进行了更新...

// 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) {
    }
});

I'd like to add one thing to happytime harry's answer . 我想在happytime harry的回答中添加一件事。

Sometimes the first writes to the stream happens before the stream listener is added. 有时,第一次写入流发生在添加流侦听器之前。 Then streamAppended on the listener is never called for those writes so output is lost. 然后,从不为这些写入调用streamAppended on listener,因此输出会丢失。

See for example this bug . 例如,请参阅此错误 I think happytime harry's solution might have this problem. 我认为快乐时候哈里的解决方案可能有这个问题。 I myself registered my stream listener in ILaunchListener.launchChanged and this happened 4/5 times. 我自己在ILaunchListener.launchChanged注册了我的流监听ILaunchListener.launchChanged ,这发生了4/5次。

If one wants to be sure to get all the output from a stream then the IStreamMonitor.getContents method can be used to fetch the output that happened before the listener got added. 如果想要确保从流中获取所有输出,则可以使用IStreamMonitor.getContents方法获取在添加侦听器之前发生的输出。

The following is an attempt on a utility method that handles this. 以下是对处理此问题的实用程序方法的尝试。 It is based on the code in ProcessConsole . 它基于ProcessConsole的代码。

/**
 * Adds listener to monitor, and calls listener with any content monitor already has.
 * NOTE: This methods synchronises on monitor while listener is called. Listener may
 * not wait on any thread that waits for monitors monitor, what would result in dead-lock.
 */
public static void addAndNotifyStreamListener(IStreamMonitor monitor, IStreamListener listener) {
    // Synchronise on monitor to prevent writes to stream while we are adding listener.
    // It's weird to synchronise on monitor because that's a shared object, but that's 
    // what ProcessConsole does.  
    synchronized (monitor) {
        String contents = monitor.getContents();
        if (!contents.isEmpty()) {
            // Call to unknown code while synchronising on monitor. This is dead-lock prone!
            // Listener must not wait for other threads that are waiting in line to 
            // synchronise on monitor.
            listener.streamAppended(contents, monitor);
        }
        monitor.addListener(listener);
    }
}

PS: There is some weird stuff going on in ProcessConsole.java . PS: ProcessConsole.java有一些奇怪的东西。 Why is the content buffering switched of from the ProcessConsole.StreamListener constructor?! 为什么从ProcessConsole.StreamListener构造函数切换内容缓冲?! If the ProcessConsole.StreamListener runs before this one maybe this solution doesn't work. 如果ProcessConsole.StreamListener在此之前运行,则此解决方案可能无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM