1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.giraph.utils;
20
21 import java.util.concurrent.Callable;
22 import org.apache.log4j.Logger;
23
24 /**
25 * A wrapper to improve debugging. It passes the call() invocation to the
26 * provided callable, and upon any exception logs the stacktrace and rethrows
27 * the exception. The logging functionality is missing in FutureTask.
28 *
29 * @param <V> Return type of call()
30 */
31 public class LogStacktraceCallable<V> implements Callable<V> {
32 /** Class logger */
33 private static final Logger LOG =
34 Logger.getLogger(LogStacktraceCallable.class);
35
36 /** Pass call() to this callable. */
37 private final Callable<V> callable;
38 /** Uncaught exception handler, if any */
39 private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
40
41 /**
42 * Construct an instance that will pass call() to the given callable.
43 *
44 * @param callable Callable
45 */
46 public LogStacktraceCallable(Callable<V> callable) {
47 this(callable, null);
48 }
49
50 /**
51 * Construct an instance that will pass call() to the given callable.
52 *
53 * @param callable Callable
54 * @param uncaughtExceptionHandler Uncaught exception handler, if any
55 *
56 *
57 */
58 public LogStacktraceCallable(Callable<V> callable,
59 Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
60 this.callable = callable;
61 this.uncaughtExceptionHandler = uncaughtExceptionHandler;
62 }
63
64 @Override
65 public V call() throws Exception {
66 try {
67 return callable.call();
68 // We catch, log stack trace of, and rethrow all exceptions. It's OK to
69 // skip style check.
70 // CHECKSTYLE: stop IllegalCatch
71 } catch (Exception e) {
72 // CHECKSTYLE: resume IllegalCatch
73 LOG.error("Execution of callable failed", e);
74 if (uncaughtExceptionHandler != null) {
75 uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), e);
76 }
77 throw e;
78 }
79 }
80 }