ripper234
ripper234

Reputation: 230038

Output from anonymous classes?

How can I get output from Java anonymous classes? In .Net I would use closures.

executor = Executors.newSingleThreadExecutor();
final Runnable runnable = new Runnable() {
  public Exception exception;

  @Override
  public void run() {
    try {
      doSomething();
    }
    catch (Exception exception) {
      // I'd like to report this exception, but how?
      // the exception member is not readable from outside the class (without reflection...)
      this.exception = exception;
    }
  }
};

executor.submit(runnable);

// Here I'd like to check if there was an exception

Upvotes: 0

Views: 910

Answers (5)

PanCrit
PanCrit

Reputation: 2718

If you declare the exception to be final, the anonymous class will be able to store the value there, and you can check the variable when the run() is done.

Edit to add: Sorry, I meant to make it a final array of one exception. Idea does this automatically for me, so I often forget about the extra redirection.

final Exception[] except;

Upvotes: -2

akf
akf

Reputation: 39485

You could wrap your thrown exception in a RuntimeException and put your executor.submit() call in a try/catch block:

executor = Executors.newSingleThreadExecutor();
final Runnable runnable = new Runnable() {

 @Override
  public void run() {
    try {
     doSomething();
    } catch (Exception exception) {
       throw new RuntimeException(exception);
    }
  }
};

try{ 
 executor.submit(runnable);
} catch (Throwable t) {
  Throwable cause = t.getCause();
  //do what you want with the cause
}

Upvotes: 0

Rick
Rick

Reputation: 3840

Hackish.... but, you could have a static variable/method that the Runnable calls to report the exception

public class Driver {
static Exception exec;
static final Runnable runnable = new Runnable() {
    public Exception exception;

    public void run() {
      try {
          throw new Exception("asdf");
      }
      catch (Exception exception) {
          exec = exception;
      }
    }
  };

public static void main(String[] args) throws Exception{
    ExecutorService e = Executors.newSingleThreadExecutor();
    e.submit(runnable);
    e.shutdown();
    while(e.isShutdown()==false){
        Thread.sleep(2000);
    }
    System.out.println(exec);

}

Upvotes: 0

Mark
Mark

Reputation: 29119

To obtain an exception from a task run on an executor you want to use Callable instead of Runnable.

The call() method of Callable can throw checked exceptions. When you call get() on your Future instance it will throw an ExecutionException if your call() method threw a checked exception. You can then access the underlying checked exception by calling getCause() on the ExecutionException.

Upvotes: 2

andri
andri

Reputation: 11292

The Executor interface offers no way to do this. However, when you call newSingleThreadExecutor() you will get an ExecutorService which contains functionality for that.

Calling ExecutorService.submit() returns an instance of Future<?>, which you can use to get the result value of the computation.

If the execution resulted in an exception, calling get will cause an ExecutionException to be thrown.

Upvotes: 7

Related Questions