View Javadoc

1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.util.internal;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.regex.Pattern;
21  
22  import org.jboss.netty.channel.ChannelPipeline;
23  import org.jboss.netty.channel.SimpleChannelHandler;
24  import org.jboss.netty.util.DebugUtil;
25  import org.jboss.netty.util.ThreadRenamingRunnable;
26  
27  /**
28   * Simplifies an exception stack trace by removing unnecessary
29   * {@link StackTraceElement}s.  Please note that the stack trace simplification
30   * is disabled if {@linkplain DebugUtil debug mode} is turned on.
31   */
32  public final class StackTraceSimplifier {
33  
34      private static final boolean SIMPLIFY_STACK_TRACE = !DebugUtil.isDebugEnabled();
35      private static final Pattern EXCLUDED_STACK_TRACE =
36          Pattern.compile(
37                  "^org\\.jboss\\.netty\\." +
38                  "(util\\.(ThreadRenamingRunnable|internal\\.DeadLockProofWorker)" +
39                  "|channel\\.(SimpleChannel(Upstream|Downstream)?Handler|(Default|Static)ChannelPipeline.*))(\\$.*)?$");
40  
41      /**
42       * Removes unnecessary {@link StackTraceElement}s from the specified
43       * exception. {@link ThreadRenamingRunnable}, {@link SimpleChannelHandler},
44       * and {@link ChannelPipeline} implementations will be dropped from the
45       * trace.
46       */
47      public static void simplify(Throwable e) {
48          if (!SIMPLIFY_STACK_TRACE) {
49              return;
50          }
51  
52          if (e.getCause() != null) {
53              simplify(e.getCause());
54          }
55  
56          StackTraceElement[] trace = e.getStackTrace();
57          if (trace == null || trace.length == 0) {
58              return;
59          }
60  
61          // Perhaps Netty bug.  Let us not strip things out.
62          if (EXCLUDED_STACK_TRACE.matcher(trace[0].getClassName()).matches()) {
63              return;
64          }
65  
66          List<StackTraceElement> simpleTrace =
67              new ArrayList<StackTraceElement>(trace.length);
68  
69          simpleTrace.add(trace[0]);
70  
71          // Remove unnecessary stack trace elements.
72          for (int i = 1; i < trace.length; i ++) {
73              if (EXCLUDED_STACK_TRACE.matcher(trace[i].getClassName()).matches()) {
74                  continue;
75              }
76              simpleTrace.add(trace[i]);
77          }
78  
79          e.setStackTrace(
80                  simpleTrace.toArray(new StackTraceElement[simpleTrace.size()]));
81      }
82  
83      private StackTraceSimplifier() {
84          // Unused
85      }
86  }