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.logging.log4j.core.util; 018 019import java.io.IOException; 020import java.io.InterruptedIOException; 021import java.io.LineNumberReader; 022import java.io.PrintWriter; 023import java.io.StringReader; 024import java.io.StringWriter; 025import java.lang.reflect.UndeclaredThrowableException; 026import java.util.ArrayList; 027import java.util.List; 028 029/** 030 * Helps with Throwable objects. 031 */ 032public final class Throwables { 033 034 private Throwables() { 035 } 036 037 /** 038 * Has no effect on Java 6 and below. 039 * 040 * @param throwable a Throwable 041 * @param suppressedThrowable a suppressed Throwable 042 * @see Throwable#addSuppressed(Throwable) 043 * @deprecated If compiling on Java 7 and above use {@link Throwable#addSuppressed(Throwable)}. 044 * Marked as deprecated because Java 6 is deprecated. Will be removed in 2.5. 045 */ 046 @Deprecated 047 public static void addSuppressed(final Throwable throwable, final Throwable suppressedThrowable) { 048 throwable.addSuppressed(suppressedThrowable); 049 } 050 051 /** 052 * Returns the deepest cause of the given {@code throwable}. 053 * 054 * @param throwable the throwable to navigate 055 * @return the deepest throwable or the given throwable 056 */ 057 public static Throwable getRootCause(final Throwable throwable) { 058 Throwable cause; 059 Throwable root = throwable; 060 while ((cause = root.getCause()) != null) { 061 root = cause; 062 } 063 return root; 064 } 065 066 /** 067 * Has no effect on Java 6 and below. 068 * 069 * @param throwable a Throwable 070 * @return see Java 7's {@link Throwable#getSuppressed()} 071 * @see Throwable#getSuppressed() 072 * @deprecated If compiling on Java 7 and above use {@link Throwable#getSuppressed()}. Marked as deprecated because 073 * Java 6 is deprecated. Will be removed 2.5. 074 */ 075 @Deprecated 076 public static Throwable[] getSuppressed(final Throwable throwable) { 077 return throwable.getSuppressed(); 078 } 079 080 /** 081 * Returns true if the getSuppressed method is available. 082 * 083 * @return True if getSuppressed is available. As of 2.4, always returns true. 084 * @deprecated Will be removed in 2.5. As of 2.4, always returns true. 085 */ 086 @Deprecated 087 public static boolean isGetSuppressedAvailable() { 088 return true; 089 } 090 091 /** 092 * Converts a Throwable stack trace into a List of Strings. 093 * 094 * @param throwable the Throwable 095 * @return a List of Strings 096 */ 097 public static List<String> toStringList(final Throwable throwable) { 098 final StringWriter sw = new StringWriter(); 099 final PrintWriter pw = new PrintWriter(sw); 100 try { 101 throwable.printStackTrace(pw); 102 } catch (final RuntimeException ex) { 103 // Ignore any exceptions. 104 } 105 pw.flush(); 106 final List<String> lines = new ArrayList<>(); 107 final LineNumberReader reader = new LineNumberReader(new StringReader(sw.toString())); 108 try { 109 String line = reader.readLine(); 110 while (line != null) { 111 lines.add(line); 112 line = reader.readLine(); 113 } 114 } catch (final IOException ex) { 115 if (ex instanceof InterruptedIOException) { 116 Thread.currentThread().interrupt(); 117 } 118 lines.add(ex.toString()); 119 } finally { 120 Closer.closeSilently(reader); 121 } 122 return lines; 123 } 124 125 /** 126 * Rethrows a {@link Throwable}, wrapping checked exceptions into an {@link UndeclaredThrowableException}. 127 * 128 * @param t the Throwable to throw. 129 * @throws RuntimeException if {@code t} is a RuntimeException 130 * @throws Error if {@code t} is an Error 131 * @throws UndeclaredThrowableException if {@code t} is a checked Exception 132 * @since 2.1 133 */ 134 public static void rethrow(final Throwable t) { 135 if (t instanceof RuntimeException) { 136 throw (RuntimeException) t; 137 } 138 if (t instanceof Error) { 139 throw (Error) t; 140 } 141 throw new UndeclaredThrowableException(t); 142 } 143}