View Javadoc
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 }