Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Newcomers » Newcomers » Eclipse hangs when I'm running a script(Does Eclipse plugins have an console output limit of 500 characters?)
Eclipse hangs when I'm running a script [message #493395] Sun, 25 October 2009 19:17 Go to next message
Henrik Garbergs is currently offline Henrik GarbergsFriend
Messages: 5
Registered: October 2009
Junior Member
Hi!

I'm running ruby scripts through "External tools" in Eclipse. I have a prepare-script (X) that triggers a Eclipse listener (plugin) that runs another script (Y). In other words:
X - plugin - Y

The problem is that when Y produces more than 500 characters of output, Eclipse hangs. I've replaced Y with a dummy script that just do printf's, to make sure it's not a script issue. And indeed, it seems that the length of the console output (the number of characters) is the key.

When I run Y standalone or in Eclipse without the plugin, it works perfectly even with very large outputs. So I believe I'm missing something with the plugin here. Can anyone shine some light on this please?

(I'm on WinXP SP3, Eclipse 3.4.1)

/Henrik
Re: Eclipse hangs when I'm running a script [message #493405 is a reply to message #493395] Mon, 26 October 2009 01:23 Go to previous messageGo to next message
David Wegener is currently offline David WegenerFriend
Messages: 1445
Registered: July 2009
Senior Member
Henrik Garbergs wrote:
> Hi!
>
> I'm running ruby scripts through "External tools" in Eclipse. I have a
> prepare-script (X) that triggers a Eclipse listener (plugin) that runs
> another script (Y). In other words:
> X - plugin - Y
>
> The problem is that when Y produces more than 500 characters of output,
> Eclipse hangs. I've replaced Y with a dummy script that just do
> printf's, to make sure it's not a script issue. And indeed, it seems
> that the length of the console output (the number of characters) is the
> key.
>
> When I run Y standalone or in Eclipse without the plugin, it works
> perfectly even with very large outputs. So I believe I'm missing
> something with the plugin here. Can anyone shine some light on this please?
>
> (I'm on WinXP SP3, Eclipse 3.4.1)
>
> /Henrik
>
How are you invoking script Y? My guess is that you need to process the
stdout/stderr for the process you create to run Y. The process is
hitting the output buffer limit and blocking until there is room in the
buffer for additional output.
Re: Eclipse hangs when I'm running a script [message #493500 is a reply to message #493405] Mon, 26 October 2009 14:44 Go to previous messageGo to next message
Henrik Garbergs is currently offline Henrik GarbergsFriend
Messages: 5
Registered: October 2009
Junior Member
This is how the plugin starts the script:

public class scriptListener implements IPatternMatchListenerDelegate {
  ...
  public void matchFound(PatternMatchEvent event) {
    ...
    PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
        public void run() {
            ...
            process = Runtime.getRuntime().exec("myscript "+arguments);
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            process.waitFor();
            while((line = in.readLine()) != null)
                output+=(line+"\n");
            ...etc...


How can I find out where the hanging occurs? Is it the "BufferedReader" that overflows, or maybe the "process.waitFor"?

/Henrik
Re: Eclipse hangs when I'm running a script [message #493518 is a reply to message #493500] Mon, 26 October 2009 15:20 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: wegener.cboenospam.com

"Henrik Garbergs" <henrik.garbergs@gmail.com> wrote in message
news:hc4cjl$vu7$1@build.eclipse.org...
> This is how the plugin starts the script:
>
> public class scriptListener implements IPatternMatchListenerDelegate {
> ...
> public void matchFound(PatternMatchEvent event) {
> ...
> PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
> public void run() {
> ...
> process = Runtime.getRuntime().exec("myscript "+arguments);
> BufferedReader in = new BufferedReader(new
InputStreamReader(process.getInputStream()));
> BufferedReader err = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
> process.waitFor();
> while((line = in.readLine()) != null)
> output+=(line+"\n");
> ...etc...
>
> How can I find out where the hanging occurs? Is it the "BufferedReader"
that overflows, or maybe the "process.waitFor"?
>
> /Henrik

I can see a number of issues with this snippet. First, you are executing
the script process on the SWT Display thread. This will lock up your GUI
untill the process completes. You should be running the script on a thread
other than the display thread and then use the syncExec call to display the
results in your GUI. The process.waitFor is waiting for the process to
exit. If the process fills up the buffer, it won't exit until you read the
data to empty the buffer. This means that the waitFor method will not
return and you will never get to the code to process the input. Finally,
the loop you have will only process the stdout data from the script. It
will not process the stderr data. You can't process both stdout and stderr
in the same loop without one blocking the other. You will need to kick off
a separate thread to process each stream separately.
Re: Eclipse hangs when I'm running a script [message #879592 is a reply to message #493518] Thu, 31 May 2012 13:41 Go to previous message
Henrik Garbergs is currently offline Henrik GarbergsFriend
Messages: 5
Registered: October 2009
Junior Member
Hi!

I'm sorry, I forgot to reply on this subject. Your advice was very useful and it helped me fix the code. Thank you!

Below is an overview of how I change the code. I didn't fix anything about threads, just the handling of how the plugin reads from the script. I'm just supplying the code here so that anyone else that find this thread maybe can get some help.

public class scriptListener implements IPatternMatchListenerDelegate {
  ...
  public void matchFound(PatternMatchEvent event) {
    ...
    PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
        public void run() {
            ...
            // This closes all old consoles.
            ConsolePlugin.getDefault().getConsoleManager().removeConsoles(
                 ConsolePlugin.getDefault().getConsoleManager().getConsoles()
            );
        
            // Create a new console for the script result.
            outConsole = new MessageConsole("myscript results", null);
            ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { outConsole } );
        
            // Create a stream to the console and print the scripts output there.
            MessageConsoleStream consoleStream = outConsole.newMessageStream();
            
            // Start the external script and set up streams to read its output.
            process = Runtime.getRuntime().exec("myscript "+arguments);
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));

            boolean break_on_next = false;
                  boolean ready = false;
                  for (waitIndex = 0; waitIndex < (pluginMaxWaitTimeInSeconds*10); waitIndex++) {
                
                    // Read the input stream, i.e. ordinary output from the script.
                    ready = in.ready();          // Check if the next read operation 
                                                 // is guaranteed not to block for input.
                    while (ready == true) {      // Keep reading as long as the stream
                                                 // is ready for a new read.                        
                        line = in.readLine();    // Read one line of output.
                        if (line != null) {
                            consoleStream.println(line);
                            consoleStream.flush();
                            ready = in.ready();    // Check if the stream is 
                                                   // ready for a new read.
                        }
                        else
                            ready = false;
                    }
                    
                    // Read the error stream, i.e. error messages from the script.            
                    ready = err.ready();
                    while (ready == true) {            // For comments about this code,
                                                       // see similar code above.                    
                        line = err.readLine();
                        if (line != null) {
                            consoleStream.println(line);
                            consoleStream.flush();
                            ready = err.ready();
                        }
                        else
                            ready = false;
                    }
                    
                    try {
                        // This code is a bit special since we want to do
                        // the last read from the scripts streams
                        // _after_ the script for sure has finished. 
                        // If the script has ended, then the for-loop
                        // above should end on the next loop.
                        if (break_on_next == true)
                            break;
                        
                        process.exitValue();      // The return value is ignored.
                        break_on_next = true;     // When this line is reached there was
                                                  // no exception from exitValue(), i.e. 
                                                  // the process is finished. Break the for-loop
                                                  // after next readLine.
                        
                    } catch (IllegalThreadStateException e) {
                        // This exception means that the subprocess represented by this Process object 
                        // has not yet terminated. So the for-loop above should run again.                    
                        try {
                            Thread.sleep(100);    // Wait a while for the script to execute (milliseconds).
                        } catch (InterruptedException ie) {
              }
                    }
                } // End of for-loop            
        
            } catch (IOException e1) {
                consoleStream.print( "Plugin error!" );
            }
        ...
Previous Topic:Gmail as connector for task repository
Next Topic:Eclipse RCP and web-based GUIs
Goto Forum:
  


Current Time: Sun May 12 14:26:00 GMT 2024

Powered by FUDForum. Page generated in 0.09019 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top