001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.thread; 018 019import org.slf4j.Logger; 020import org.slf4j.LoggerFactory; 021 022import java.util.TimerTask; 023 024/** 025 * A TimeTask for a Runnable object 026 * 027 */ 028public class SchedulerTimerTask extends TimerTask { 029 private static final Logger LOGGER = LoggerFactory.getLogger(SchedulerTimerTask.class); 030 031 private final Runnable task; 032 033 public SchedulerTimerTask(Runnable task) { 034 this.task = task; 035 } 036 037 public void run() { 038 try { 039 this.task.run(); 040 } catch (Error error) { 041 // Very bad error. Can't swallow this but can log it. 042 LOGGER.error("Scheduled task error", error); 043 throw error; 044 } catch (Exception exception) { 045 // It is a known issue of java.util.Timer that if a TimerTask.run() method throws an exception, the 046 // Timer's thread exits as if Timer.cancel() had been called. This makes the Timer completely unusable from 047 // that point on - whenever the Timer triggers there is an 'IllegalStateException: Timer already cancelled' 048 // and the task does not get executed. 049 // 050 // In practice, this makes the ActiveMQ client unable to refresh connections to brokers. Generally, tasks 051 // are well coded to not throw exceptions but if they do, problems ensue... 052 // 053 // The answer, here, is to log the exception and then carry on without throwing further. This gives the 054 // added benefit that, having seen the exception thrown, one can then go and fix the offending task! 055 LOGGER.error("Scheduled task exception", exception); 056 } 057 } 058}