1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache license, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the license for the specific language governing permissions and 15 * limitations under the license. 16 */ 17 package org.apache.logging.log4j.core.util; 18 19 import java.io.IOException; 20 import java.io.InterruptedIOException; 21 import java.io.LineNumberReader; 22 import java.io.PrintWriter; 23 import java.io.StringReader; 24 import java.io.StringWriter; 25 import java.lang.reflect.UndeclaredThrowableException; 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** 30 * Helps with Throwable objects. 31 */ 32 public final class Throwables { 33 34 private Throwables() { 35 } 36 37 /** 38 * Has no effect on Java 6 and below. 39 * 40 * @param throwable a Throwable 41 * @param suppressedThrowable a suppressed Throwable 42 * @see Throwable#addSuppressed(Throwable) 43 * @deprecated If compiling on Java 7 and above use {@link Throwable#addSuppressed(Throwable)}. 44 * Marked as deprecated because Java 6 is deprecated. Will be removed in 2.5. 45 */ 46 @Deprecated 47 public static void addSuppressed(final Throwable throwable, final Throwable suppressedThrowable) { 48 throwable.addSuppressed(suppressedThrowable); 49 } 50 51 /** 52 * Returns the deepest cause of the given {@code throwable}. 53 * 54 * @param throwable the throwable to navigate 55 * @return the deepest throwable or the given throwable 56 */ 57 public static Throwable getRootCause(final Throwable throwable) { 58 Throwable cause; 59 Throwable root = throwable; 60 while ((cause = root.getCause()) != null) { 61 root = cause; 62 } 63 return root; 64 } 65 66 /** 67 * Has no effect on Java 6 and below. 68 * 69 * @param throwable a Throwable 70 * @return see Java 7's {@link Throwable#getSuppressed()} 71 * @see Throwable#getSuppressed() 72 * @deprecated If compiling on Java 7 and above use {@link Throwable#getSuppressed()}. Marked as deprecated because 73 * Java 6 is deprecated. Will be removed 2.5. 74 */ 75 @Deprecated 76 public static Throwable[] getSuppressed(final Throwable throwable) { 77 return throwable.getSuppressed(); 78 } 79 80 /** 81 * Returns true if the getSuppressed method is available. 82 * 83 * @return True if getSuppressed is available. As of 2.4, always returns true. 84 * @deprecated Will be removed in 2.5. As of 2.4, always returns true. 85 */ 86 @Deprecated 87 public static boolean isGetSuppressedAvailable() { 88 return true; 89 } 90 91 /** 92 * Converts a Throwable stack trace into a List of Strings. 93 * 94 * @param throwable the Throwable 95 * @return a List of Strings 96 */ 97 public static List<String> toStringList(final Throwable throwable) { 98 final StringWriter sw = new StringWriter(); 99 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 }