using org.eclipse.core.runtime.jobs.Job to run external process [message #276883] |
Tue, 30 November 2004 13:38  |
Eclipse User |
|
|
|
Hi,
I am using org.eclipse.core.runtime.jobs.Job to run an external make
process. It seems to work, but I have some questions regarding returning
the status of the job to the action that schedules the job. Here is a
sample code.
// Action Delegate class
public class XYZActionDelegate implements IObjectActionDelegate
{
public void run ( IAction action )
{
// Process the action to get the selection etc.
...
// Create and schedule the Job.
XYZJob job = new XYZJob( name );
job.schedule();
}
}
// Job class
public XYZJob extends Job
{
public IStatus run ( IProgressMonitor monitor )
{
// Set monitor status etc.
....
// Run the process.
try
{
Process proc = Runtime.getRuntime().exec( cmd );
// capture the output and error messages from the process
// in separate threads.
....
// Wait for the process to finish
int exit = proc.waitFor();
}
catch ( Exception e )
{
// Process exception
...
}
// Return status
return status;
}
}
This seems to work. The process executes, the progress monitor dialog is
displayed etc. My questions are:
1. Since the Job runs in a separate thread, how can I communicate the
status of the job to my action delegate. Do I need to register a
IJobChangeListener?
2. When the user cancel's the job from the progress monitor dialog, I
need to stop the process. I looked into the code for Job class. When a
cancel action is performed, the "cancel" method of the job gets called.
But this is a "final" method, so I cannot override the method. So how do
I kill the running process. If I add a IJobChangeListener and kill the
process in the "Done" method, the thread that is waiting for the process
to finish will resume, the run method will return a status and the Done"
method of the IJobChangeListener will be called again. I kill the
process in the "Done" method only if it is running. That will probaly
take care of the second invocation of the "Done" method. But is this the
right way to do this. Also, this does not address the issue of
communicating the status to my action delegate.
Any suggestion to implement is appreciated.
Thanks for your help.
Anand
--
____________________________________________________________ _____________________
Anand Narasimhan
anandn@cisco.com
|
|
|
Re: using org.eclipse.core.runtime.jobs.Job to run external process [message #276953 is a reply to message #276883] |
Wed, 01 December 2004 14:56   |
Eclipse User |
|
|
|
Originally posted by: john.eclipsefaq.org
Why do you need a job in this case? If you are running an external
Process, it already executes asynchronously. I'm guessing you are just
using the job in order to show nice progress for the process in the UI?
To answer your questions:
1. You can find out a job's state by calling getState(), or by adding a
job listener to the job, which will be notified of any job state changes.
2. This is a bit tricky. A job can either be canceled programmatically
(by calling Job.cancel() or by the end user via the progress view. In
both of these cases, the cancelation request simply sets a flag on job's
progress monitor. Calling IProgressMonitor.isCanceled() on the monitor
passed to the job's run method is the way to find out if a cancelation
request has occurred. The problem is, in your case you cannot check this
flag if the job is blocked on Process.waitFor. I suppose one approach is
to write a loop that sleeps, then periodically checks
Process.exitValue(). The loop would continue until exitValue() returns
normally. That way the loop could also check for cancelation.
public IStatus run(IProgressMonitor pm) {
.. create the process and setup stream handling
while (true) {
try {
Thread.sleep(100);
proc.exitValue();
break;
} catch (Exception e) {
//keep looping
}
}
return Status.OK_STATUS;
}
Anand Narasimhan wrote:
> 1. Since the Job runs in a separate thread, how can I communicate the
> status of the job to my action delegate. Do I need to register a
> IJobChangeListener?
>
> 2. When the user cancel's the job from the progress monitor dialog, I
> need to stop the process. I looked into the code for Job class. When a
> cancel action is performed, the "cancel" method of the job gets called.
> But this is a "final" method, so I cannot override the method. So how do
> I kill the running process. If I add a IJobChangeListener and kill the
> process in the "Done" method, the thread that is waiting for the process
> to finish will resume, the run method will return a status and the Done"
> method of the IJobChangeListener will be called again. I kill the
> process in the "Done" method only if it is running. That will probaly
> take care of the second invocation of the "Done" method. But is this the
> right way to do this. Also, this does not address the issue of
> communicating the status to my action delegate.
>
> Any suggestion to implement is appreciated.
>
> Thanks for your help.
>
> Anand
|
|
|
Re: using org.eclipse.core.runtime.jobs.Job to run external process [message #276955 is a reply to message #276953] |
Wed, 01 December 2004 15:21  |
Eclipse User |
|
|
|
Thanks for the reply.
John Arthorne wrote:
> Why do you need a job in this case? If you are running an external
> Process, it already executes asynchronously. I'm guessing you are just
> using the job in order to show nice progress for the process in the UI?
> To answer your questions:
Yes. I want to use the Job class to make use of the Progress monitor
infrastructure provided by eclipse.
>
> 1. You can find out a job's state by calling getState(), or by adding a
> job listener to the job, which will be notified of any job state changes.
>
> 2. This is a bit tricky. A job can either be canceled programmatically
> (by calling Job.cancel() or by the end user via the progress view. In
> both of these cases, the cancelation request simply sets a flag on job's
> progress monitor. Calling IProgressMonitor.isCanceled() on the monitor
> passed to the job's run method is the way to find out if a cancelation
> request has occurred. The problem is, in your case you cannot check this
> flag if the job is blocked on Process.waitFor. I suppose one approach is
> to write a loop that sleeps, then periodically checks
> Process.exitValue(). The loop would continue until exitValue() returns
> normally. That way the loop could also check for cancelation.
>
> public IStatus run(IProgressMonitor pm) {
> .. create the process and setup stream handling
> while (true) {
> try {
> Thread.sleep(100);
> proc.exitValue();
> break;
> } catch (Exception e) {
> //keep looping
> }
> }
> return Status.OK_STATUS;
> }
>
I was hoping to avoid polling.
|
|
|
Powered by
FUDForum. Page generated in 0.05628 seconds