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.util; 018 019import java.util.Iterator; 020import java.util.List; 021 022import org.apache.activemq.Service; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026/** 027 * A helper class used to stop a bunch of services, catching and logging any 028 * exceptions and then throwing the first exception when everything is stoped. 029 * 030 * 031 */ 032public class ServiceStopper { 033 private Throwable firstException; 034 035 /** 036 * Stops the given service, catching any exceptions that are thrown. 037 */ 038 public void stop(Service service) { 039 try { 040 if (service != null) { 041 service.stop(); 042 } 043 } catch (Exception e) { 044 onException(service, e); 045 } 046 } 047 048 /** 049 * Performs the given code to stop some service handling the exceptions 050 * which may be thrown properly 051 */ 052 public void run(Callback stopClosure) { 053 try { 054 stopClosure.execute(); 055 } catch (Throwable e) { 056 onException(stopClosure, e); 057 } 058 } 059 060 /** 061 * Stops a list of services 062 */ 063 public void stopServices(List services) { 064 for (Iterator iter = services.iterator(); iter.hasNext();) { 065 Service service = (Service)iter.next(); 066 stop(service); 067 } 068 } 069 070 public void onException(Object owner, Throwable e) { 071 logError(owner, e); 072 if (firstException == null) { 073 firstException = e; 074 } 075 } 076 077 /** 078 * Throws the first exception that was thrown if there was one. 079 */ 080 public void throwFirstException() throws Exception { 081 if (firstException != null) { 082 if (firstException instanceof Exception) { 083 Exception e = (Exception)firstException; 084 throw e; 085 } else if (firstException instanceof RuntimeException) { 086 RuntimeException e = (RuntimeException)firstException; 087 throw e; 088 } else { 089 throw new RuntimeException("Unknown type of exception: " + firstException, firstException); 090 } 091 } 092 } 093 094 protected void logError(Object service, Throwable e) { 095 Logger log = LoggerFactory.getLogger(service.getClass()); 096 log.error("Could not stop service: " + service + ". Reason: " + e, e); 097 } 098 099}