View Javadoc
1   /*
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v2.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.classic.spi;
15  
16  import ch.qos.logback.classic.ClassicConstants;
17  import ch.qos.logback.core.CoreConstants;
18  
19  import java.io.Serializable;
20  import java.util.Objects;
21  
22  import static ch.qos.logback.classic.ClassicConstants.DECLARING_CLASS_NA;
23  import static ch.qos.logback.classic.ClassicConstants.FILENAME_NA;
24  import static ch.qos.logback.classic.ClassicConstants.LINE_NUMBER_NA;
25  import static ch.qos.logback.classic.ClassicConstants.METHOD_NAME_NA;
26  
27  public class StackTraceElementProxy implements Serializable {
28  
29      private static final long serialVersionUID = -2374374378980555982L;
30  
31      final StackTraceElement ste;
32      // save a byte or two during serialization, as we can
33      // reconstruct this field from 'ste'
34      transient private String steAsString;
35  
36      @Deprecated
37      ClassPackagingData classPackagingData;
38  
39      // See https://github.com/qos-ch/logback/issues/1040
40      static final StackTraceElement NA_SUBSTITUTE = new StackTraceElement(DECLARING_CLASS_NA, METHOD_NAME_NA,
41                                                                          FILENAME_NA, LINE_NUMBER_NA);
42  
43      public StackTraceElementProxy(StackTraceElement ste) {
44          // while null StackTraceElement is not expected, we defensively replace it with NA_SUBSTITUTE.
45          this.ste = Objects.requireNonNullElse(ste, NA_SUBSTITUTE);
46      }
47  
48      public String getSTEAsString() {
49          if (steAsString == null) {
50              steAsString = "at " + ste.toString();
51          }
52          return steAsString;
53      }
54  
55      public StackTraceElement getStackTraceElement() {
56          return ste;
57      }
58  
59      public void setClassPackagingData(ClassPackagingData cpd) {
60          if (this.classPackagingData != null) {
61              throw new IllegalStateException("Packaging data has been already set");
62          }
63          this.classPackagingData = cpd;
64      }
65  
66      public ClassPackagingData getClassPackagingData() {
67          return classPackagingData;
68      }
69  
70      @Override
71      public int hashCode() {
72          return ste.hashCode();
73      }
74  
75      @Override
76      public boolean equals(Object obj) {
77          if (this == obj)
78              return true;
79          if (obj == null)
80              return false;
81          if (getClass() != obj.getClass())
82              return false;
83          final StackTraceElementProxy other = (StackTraceElementProxy) obj;
84  
85          if (!ste.equals(other.ste)) {
86              return false;
87          }
88          if (classPackagingData == null) {
89              if (other.classPackagingData != null) {
90                  return false;
91              }
92          } else if (!classPackagingData.equals(other.classPackagingData)) {
93              return false;
94          }
95          return true;
96      }
97  
98      @Override
99      public String toString() {
100         return getSTEAsString();
101     }
102 }