Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8537829
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T10:59:33+00:00 2026-06-11T10:59:33+00:00

After a painful debugging experience, I tracked down this issue: ScheduledThreadPool does not report

  • 0

After a painful debugging experience, I tracked down this issue: ScheduledThreadPool does not report if a task fails, and does not execute a task that failed once ever again. Therefore, it is hard to keep track of the liveness of periodic jobs, short of checking them with yet other periodic tasks (via dead man’s switch or the ScheduledFuture).

Now we can hand a ScheduledThreadPool an UncaughtExceptionHandler, but not even that seems to work:

import java.util.concurrent.*;

class Test {
  public static void main(String[] args) {
    final ThreadFactory tf = new ThreadFactory() {
      private final ThreadFactory delegate = Executors.defaultThreadFactory();

      @Override public Thread newThread(final Runnable r) {
        final Thread res = delegate.newThread(r);
        res.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
          @Override
          public void uncaughtException(final Thread t, final Throwable e) {
            e.printStackTrace();
          }
        });
        return res;
      }
    };
    final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1, tf);

    final Runnable task = new Runnable() {
      private int c = 0;

      @Override
      public void run() {
        if ( c++ == 5 ) {
          throw new ArrayIndexOutOfBoundsException("Runtime error!");
        }

        System.out.println("Reached " + c);
      }
    };

    exec.scheduleWithFixedDelay(task, 1, 1, TimeUnit.SECONDS);
  }
}

The output of this program is simply (Oracle Java SE (64-Bit Server) 1.7.0_06-b24)

Reached 1
Reached 2
Reached 3
Reached 4
Reached 5

and then it hangs (by design).

I can always try-catch the whole task, but that feels ugly; the UncaughtExceptionHandler should do that already!

Is there an API-solution for this issue? Did I do something wrong, or is it a bug?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T10:59:34+00:00Added an answer on June 11, 2026 at 10:59 am

    The currency thread pools capture all exceptions and place then in the Future object for you to inspect. UncaughtExceptionHandler is only for exception the thread doesn’t catch and kills the thread, which in this case would only be for exception thrown by the thread pool code.

    A simple way around this is to wrap your runnable.

    public class ExceptionHandlingScheduledExecutor extends ScheduledThreadPoolExecutor {
        private final Thread.UncaughtExceptionHandler ueh;
    
        public ExceptionHandlingScheduledExecutor(int corePoolSize, Thread.UncaughtExceptionHandler ueh) {
            super(corePoolSize);
            this.ueh = ueh;
        }
    
        @Override
        public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
            return super.schedule(wrap(command), delay, unit);
        }
    
        @Override
        public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
            return super.schedule(wrap(callable), delay, unit); 
        }
    
        @Override
        public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
            return super.scheduleAtFixedRate(wrap(command), initialDelay, period, unit);
        }
    
        @Override
        public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
            return super.scheduleWithFixedDelay(wrap(command), initialDelay, delay, unit);
        }
    
        @Override
        public void execute(Runnable command) {
            super.execute(wrap(command));
        }
    
        @Override
        public Future<?> submit(Runnable task) {
            return super.submit(wrap(task));
        }
    
        @Override
        public <T> Future<T> submit(Runnable task, T result) {
            return super.submit(wrap(task), result);
        }
    
        @Override
        public <T> Future<T> submit(Callable<T> task) {
            return super.submit(wrap(task));
        }
    
        private Runnable wrap(final Runnable runnable) {
            return new Runnable() {
                @Override
                public void run() {
                    try {
                        runnable.run();
                    } catch (final Throwable t) {
                        ueh.uncaughtException(Thread.currentThread(), t);
                        throw t;
                    }
                }
            };
        }
    
        private <T> Callable<T> wrap(final Callable<T> callable) {
            return new Callable<T>() {
                @Override
                public T call() throws Exception {
                    try {
                        return callable.call();
                    } catch (Throwable t) {
                        ueh.uncaughtException(Thread.currentThread(), t);
                        throw t;
                    }
                }
            };
        }
    }
    

    You can sub-class the ThreadPoolExecutor to do this transparently.


    You can also use a cached thread pool to handle exception but this is is more complicated.

    One way to use the returned Future in a transparent way is to sub-class ScheduledThreadPoolExecutor (or any Executor, for that matter):

    class MyScheduledExecutor extends ScheduledThreadPoolExecutor {
      private final Thread.UncaughtExceptionHandler ueh;
      private final ExecutorService futureService = Executors.newCachedThreadPool();
    
      public MyScheduledExecutor(int corePoolSize, Thread.UncaughtExceptionHandler ueh) {
        super(corePoolSize);
        this.ueh = ueh;
      }
    
      // Copy other constructors
    
      @Override
      public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                       long initialDelay,
                                                       long delay,
                                                       TimeUnit unit) {
        final ScheduledFuture<?> f = super.scheduleWithFixedDelay(command, initialDelay, delay, unit);
        futureService.submit(new Runnable() {
          @Override
          public void run() {
            try {
              f.get();
            } catch (Throwable t ) {
              ueh.uncaughtException(null, t.getCause());
            }
          }
        };
    
        return f;
      }
    
      // Do similarly for other submit/schedule methods
    }
    

    And use it like this:

    final ScheduledThreadPoolExecutor exec = new MyScheduledExecutor(1, new Thread.UncaughtExceptionHandler() {
          @Override
          public void uncaughtException(final Thread t, final Throwable e) {
            e.printStackTrace();
          }
        });
    

    Now the output is as desired:

    Reached 1
    Reached 2
    Reached 3
    Reached 4
    Reached 5
    java.lang.ArrayIndexOutOfBoundsException: Runtime error!
       ...
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Ok, this is painful for me because yes, I've been coding ASP.NET after classic
After reading this question , I've learned that denormalization is not a solution for
I'm not sure that this is a bug since after searching I can't find
After some painful experiences, I understand the problem of dangling pointers and double free.
After a painful search for Python XMPP library to use for XEP 060 I
After deploying WCF server (svc) on my Server, I have got this message when
This is for debugging purpose. I've got a for loop that generates some output
After following this question , I added HttpServletRequest parameter to my method. But I
I currently had this problem, that after adding a framework (in my case Sharekit),
I'm trying to migrate an existing (web-)project to roo. After some painful hours migrating

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.