[logback-dev] svn commit: r1795 - in logback/trunk: logback-classic logback-classic/src/main/java/ch/qos/logback/classic/pattern logback-classic/src/main/java/ch/qos/logback/classic/spi logback-classic/src/test/java/ch/qos/logback/classic/pattern logback-classic/src/test/java/ch/qos/logback/classic/spi logback-classic/src/test/java/ch/qos/logback/classic/spi/special logback-classic/src/test/java/ch/qos/logback/classic/util logback-core/src/main/java/ch/qos/logback/core/util
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Mon Sep 8 17:42:48 CEST 2008
Author: ceki
Date: Mon Sep 8 17:42:48 2008
New Revision: 1795
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java
- copied, changed from r1794, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackageInfo.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingDataCalculator.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackageInfo.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackageInfoCalculator.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageInfoTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageVersionCalculatorTest.java
Modified:
logback/trunk/logback-classic/pom.xml
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java
Log:
LBGENERAL-23
This code attempts to guarantee that the extracted class packaging information
is extracting using the *exact* same classloader was used to load a given class
in the stack frame.
Associated test cases.
Modified: logback/trunk/logback-classic/pom.xml
==============================================================================
--- logback/trunk/logback-classic/pom.xml (original)
+++ logback/trunk/logback-classic/pom.xml Mon Sep 8 17:42:48 2008
@@ -114,7 +114,6 @@
<scope>test</scope>
</dependency>
-
</dependencies>
<build>
@@ -159,9 +158,9 @@
</excludes>
</configuration>
</plugin>
-
</plugins>
+
</build>
</project>
\ No newline at end of file
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java Mon Sep 8 17:42:48 2008
@@ -9,7 +9,7 @@
*/
package ch.qos.logback.classic.pattern;
-import ch.qos.logback.classic.spi.PackageInfo;
+import ch.qos.logback.classic.spi.ClassPackagingData;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.classic.spi.ThrowableDataPoint;
@@ -20,9 +20,9 @@
protected void extraData(StringBuilder builder, ThrowableDataPoint tdp) {
StackTraceElementProxy step = tdp.getStackTraceElementProxy();
if(step != null) {
- PackageInfo pi = step.getPackageInfo();
+ ClassPackagingData pi = step.getClassPackagingData();
if(pi != null) {
- builder.append(" [").append(pi.getJarName()).append(':').append(pi.getVersion()).append(']');
+ builder.append(" [").append(pi.getCodeLocation()).append(':').append(pi.getVersion()).append(']');
}
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java Mon Sep 8 17:42:48 2008
@@ -14,7 +14,7 @@
import org.slf4j.Marker;
-import ch.qos.logback.classic.spi.PackageInfo;
+import ch.qos.logback.classic.spi.ClassPackagingData;
/**
*
@@ -22,7 +22,7 @@
*/
public class Util {
- static Map<String, PackageInfo> cache = new HashMap<String, PackageInfo>();
+ static Map<String, ClassPackagingData> cache = new HashMap<String, ClassPackagingData>();
static public boolean match(Marker marker, Marker[] markerArray) {
if (markerArray == null) {
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java (from r1794, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackageInfo.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackageInfo.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java Mon Sep 8 17:42:48 2008
@@ -11,24 +11,36 @@
import java.io.Serializable;
-public class PackageInfo implements Serializable {
+public class ClassPackagingData implements Serializable {
private static final long serialVersionUID = 637783570208674312L;
- String jarName;
- String version;
+ final String codeLocation;
+ final String version;
+ private final boolean exact;
- public PackageInfo(String jarName, String version) {
- this.jarName = jarName;
+ public ClassPackagingData(String codeLocation, String version) {
+ this.codeLocation = codeLocation;
this.version = version;
+ this.exact = true;
}
- public String getJarName() {
- return jarName;
+ public ClassPackagingData(String classLocation, String version, boolean exact) {
+ this.codeLocation = classLocation;
+ this.version = version;
+ this.exact = exact;
+ }
+
+ public String getCodeLocation() {
+ return codeLocation;
}
public String getVersion() {
return version;
}
+
+ public boolean isExact() {
+ return exact;
+ }
}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingDataCalculator.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingDataCalculator.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,245 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.classic.spi;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import sun.reflect.Reflection;
+import ch.qos.logback.classic.spi.ThrowableDataPoint.ThrowableDataPointType;
+
+/**
+ *
+ * Given a classname locate associated PackageInfo (jar name, version name).
+ *
+ * @author James Strachan
+ * @Ceki Gülcü
+ */
+public class ClassPackagingDataCalculator {
+
+ final static StackTraceElementProxy[] STEP_ARRAY_TEMPLATE = new StackTraceElementProxy[0];
+
+ HashMap<String, ClassPackagingData> cache = new HashMap<String, ClassPackagingData>();
+
+ public ClassPackagingDataCalculator() {
+ }
+
+ public void calculate(ThrowableDataPoint[] tdpArray) {
+ int steStart = 0;
+ StackTraceElementProxy[] stepArray = new StackTraceElementProxy[0];
+ do {
+ steStart = findSTEStartIndex(tdpArray, steStart+stepArray.length);
+ stepArray = getSTEPArray(tdpArray, steStart);
+ populateFrames(stepArray);
+ } while(steStart != -1);
+ }
+
+ void populateFrames(StackTraceElementProxy[] stepArray) {
+ // in the initial part of this method we populate package informnation for
+ // common stack frames
+ Throwable t = new Throwable("local stack reference");
+ StackTraceElement[] localteSTEArray = t.getStackTrace();
+ int commonFrames = STEUtil.findNumberOfCommonFrames(localteSTEArray,
+ stepArray);
+ int localFirstCommon = localteSTEArray.length - commonFrames;
+ int stepFirstCommon = stepArray.length - commonFrames;
+
+ ClassLoader lastExactClassLoader = null;
+ ClassLoader firsExactClassLoader = null;
+
+ int missfireCount = 0;
+ for (int i = 0; i < commonFrames; i++) {
+ Class callerClass = Reflection.getCallerClass(localFirstCommon + i
+ - missfireCount + 1);
+ StackTraceElementProxy step = stepArray[stepFirstCommon + i];
+ String stepClassname = step.ste.getClassName();
+
+ if (stepClassname.equals(callerClass.getName())) {
+ lastExactClassLoader = callerClass.getClassLoader();
+ if(firsExactClassLoader == null) {
+ firsExactClassLoader = callerClass.getClassLoader();
+ }
+ ClassPackagingData pi = calculateByExactType(callerClass);
+ step.setPackageInfo(pi);
+ } else {
+ missfireCount++;
+ ClassPackagingData pi = computeBySTEP(step, lastExactClassLoader);
+ step.setPackageInfo(pi);
+ }
+ }
+ populateUncommonFrames(commonFrames, stepArray, firsExactClassLoader);
+ }
+
+ int findSTEStartIndex(ThrowableDataPoint[] tdpArray, int from) {
+ int len = tdpArray.length;
+ if (from < 0 || from >= len) {
+ return -1;
+ }
+ for (int i = from; i < len; i++) {
+ if (tdpArray[i].type == ThrowableDataPointType.STEP) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private StackTraceElementProxy[] getSTEPArray(ThrowableDataPoint[] tdpArray, int from) {
+ List<StackTraceElementProxy> stepList = new LinkedList<StackTraceElementProxy>();
+ int len = tdpArray.length;
+ if (from < 0 || from >= len) {
+ return stepList.toArray(STEP_ARRAY_TEMPLATE);
+ }
+ for (int i = from; i < len; i++) {
+ final ThrowableDataPoint tdp = tdpArray[i];
+
+ if (tdp.type == ThrowableDataPointType.STEP) {
+ stepList.add(tdp.getStackTraceElementProxy());
+ } else {
+ break;
+ }
+ }
+ return stepList.toArray(STEP_ARRAY_TEMPLATE);
+ }
+
+ void populateUncommonFrames(int commonFrames, StackTraceElementProxy[] stepArray, ClassLoader firstExactClassLoader) {
+ int uncommonFrames = stepArray.length-commonFrames;
+ for (int i = 0; i < uncommonFrames; i++) {
+ StackTraceElementProxy step = stepArray[i];
+ ClassPackagingData pi = computeBySTEP(step, firstExactClassLoader);
+ step.setPackageInfo(pi);
+ }
+ }
+
+ private ClassPackagingData calculateByExactType(Class type) {
+ String className = type.getName();
+ ClassPackagingData cpd = cache.get(className);
+ if (cpd != null) {
+ return cpd;
+ }
+ String version = getImplementationVersion(type);
+ String codeLocation = getCodeLocation(type);
+ cpd = new ClassPackagingData(codeLocation, version);
+ cache.put(className, cpd);
+ return cpd;
+ }
+
+ private ClassPackagingData computeBySTEP(StackTraceElementProxy step, ClassLoader lastExactClassLoader) {
+ String className = step.ste.getClassName();
+ ClassPackagingData cpd = cache.get(className);
+ if (cpd != null) {
+ return cpd;
+ }
+ Class type = bestEffortLoadClass(lastExactClassLoader, className);
+ String version = getImplementationVersion(type);
+ String codeLocation = getCodeLocation(type);
+ cpd = new ClassPackagingData(codeLocation, version, false);
+ cache.put(className, cpd);
+ return cpd;
+ }
+
+
+ String getImplementationVersion(Class type) {
+ Package aPackage = type.getPackage();
+ if (aPackage != null) {
+ String v = aPackage.getImplementationVersion();
+ if (v == null) {
+ return "na";
+ } else {
+ return v;
+ }
+ }
+ return "na";
+
+ }
+
+ String getCodeLocation(Class type) {
+ try {
+ if (type != null) {
+ // file:/C:/java/maven-2.0.8/repo/com/icegreen/greenmail/1.3/greenmail-1.3.jar
+ URL resource = type.getProtectionDomain().getCodeSource().getLocation();
+ if (resource != null) {
+ String locationStr = resource.toString();
+ // now lets remove all but the file name
+ String result = getCodeLocation(locationStr, '/');
+ if(result != null) {
+ return result;
+ }
+ return getCodeLocation(locationStr, '\\');
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ return "na";
+ }
+
+
+ private String getCodeLocation(String locationStr, char separator) {
+ int idx = locationStr.lastIndexOf(separator);
+ if(isFolder(idx, locationStr)) {
+ idx = locationStr.lastIndexOf(separator, idx-1);
+ return locationStr.substring(idx+1);
+ } else if (idx > 0) {
+ return locationStr.substring(idx + 1);
+ }
+ return null;
+ }
+
+ private boolean isFolder(int idx, String text) {
+ return (idx != -1 && idx+1 == text.length());
+ }
+
+ private Class loadClass(ClassLoader cl, String className) {
+ if(cl == null) {
+ return null;
+ }
+ try {
+ return cl.loadClass(className);
+ } catch (ClassNotFoundException e1) {
+ return null;
+ } catch(Exception e) {
+ e.printStackTrace(); // this is unexpected
+ return null;
+ }
+
+ }
+
+ /**
+ *
+ * @param lastGuaranteedClassLoader may be null
+ * @param className
+ * @return
+ */
+ private Class bestEffortLoadClass(ClassLoader lastGuaranteedClassLoader, String className) {
+ Class result = loadClass(lastGuaranteedClassLoader, className);
+ if(result != null) {
+ return result;
+ }
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if(tccl != lastGuaranteedClassLoader) {
+ result = loadClass(tccl, className);
+ }
+ if(result != null) {
+ return result;
+ }
+
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e1) {
+ return null;
+ } catch(Exception e) {
+ e.printStackTrace(); // this is unexpected
+ return null;
+ }
+ }
+
+}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java Mon Sep 8 17:42:48 2008
@@ -10,7 +10,7 @@
final StackTraceElement ste;
private String steAsString;
- private PackageInfo pi;
+ private ClassPackagingData cpd;
StackTraceElementProxy(StackTraceElement ste) {
if(ste == null) {
@@ -26,12 +26,12 @@
return steAsString;
}
- void setPackageInfo(PackageInfo pi) {
- this.pi = pi;
+ void setPackageInfo(ClassPackagingData cpd) {
+ this.cpd = cpd;
}
- public PackageInfo getPackageInfo() {
- return pi;
+ public ClassPackagingData getClassPackagingData() {
+ return cpd;
}
@Override
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java Mon Sep 8 17:42:48 2008
@@ -11,32 +11,32 @@
import java.util.Arrays;
+import ch.qos.logback.core.CoreGlobal;
public class ThrowableProxy implements java.io.Serializable {
private static final long serialVersionUID = 6307784764626694851L;
private ThrowableDataPoint[] tdpArray;
private transient final Throwable throwable;
- private transient PackageInfoCalculator packageInfoCalculator;
+ private transient ClassPackagingDataCalculator classPackagingDataCalculator;
public ThrowableProxy(Throwable throwable) {
this.throwable = throwable;
- this.tdpArray = ThrowableToDataPointArray.convert(throwable);
+ this.tdpArray = ThrowableToDataPointArray.convert(throwable);
}
public Throwable getThrowable() {
return throwable;
}
-
-
- public PackageInfoCalculator getPackageInfoCalculator() {
- // if original instance (non-deserialized), and packageInfoCalculator
+
+ public ClassPackagingDataCalculator getClassPackagingDataCalculator() {
+ // if original instance (non-deserialized), and classPackagingDataCalculator
// is not already initialized, then create an instance
- // here we assume that (throwable == null) for deserialized instances
- if(throwable != null && packageInfoCalculator == null) {
- packageInfoCalculator = new PackageInfoCalculator();
+ // here we assume that (throwable == null) for deserialized instances
+ if (throwable != null && classPackagingDataCalculator == null) {
+ classPackagingDataCalculator = new ClassPackagingDataCalculator();
}
- return packageInfoCalculator;
+ return classPackagingDataCalculator;
}
/**
@@ -67,5 +67,31 @@
return false;
return true;
}
-
+
+ public void fullDump() {
+ StringBuilder builder = new StringBuilder();
+ for (ThrowableDataPoint tdp : getThrowableDataPointArray()) {
+ String string = tdp.toString();
+ builder.append(string);
+ extraData(builder, tdp);
+ builder.append(CoreGlobal.LINE_SEPARATOR);
+ }
+ System.out.println(builder.toString());
+ }
+
+ protected void extraData(StringBuilder builder, ThrowableDataPoint tdp) {
+ StackTraceElementProxy step = tdp.getStackTraceElementProxy();
+ if (step != null) {
+ ClassPackagingData cpd = step.getClassPackagingData();
+ if (cpd != null) {
+ if(!cpd.isExact()){
+ builder.append(" ~[") ;
+ } else {
+ builder.append(" [") ;
+ }
+ builder.append(cpd.getCodeLocation()).append(':').append(
+ cpd.getVersion()).append(']');
+ }
+ }
+ }
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java Mon Sep 8 17:42:48 2008
@@ -12,6 +12,7 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.classic.util.TeztHelper;
public class ThrowableProxyConverterTest {
@@ -45,7 +46,7 @@
@Test
public void nested() {
- Throwable t = makeNestedException(1);
+ Throwable t = TeztHelper.makeNestedException(1);
verify(t);
}
@@ -59,11 +60,5 @@
assertEquals(sw.toString(), result);
}
- Throwable makeNestedException(int level) {
- if (level == 0) {
- return new Exception("nesting level=" + level);
- }
- Throwable cause = makeNestedException(level - 1);
- return new Exception("nesting level =" + level, cause);
- }
+
}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,95 @@
+package ch.qos.logback.classic.spi;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.classic.util.TeztHelper;
+import ch.qos.logback.core.util.SystemInfo;
+
+public class BasicCPDCTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ public void verify(ThrowableDataPoint[] tdpArray) {
+ for (ThrowableDataPoint tdp : tdpArray) {
+ StackTraceElementProxy step = tdp.getStackTraceElementProxy();
+ if (step != null) {
+ assertNotNull(step.getClassPackagingData());
+ }
+ }
+ }
+
+ @Test public void otherJD() {
+ System.out.println(SystemInfo.getJavaVendor());
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ Throwable t = new Throwable("x");
+ ThrowableProxy tp = new ThrowableProxy(t);
+ ClassPackagingDataCalculator cpdc = tp.getClassPackagingDataCalculator();
+ ThrowableDataPoint[] tdpArray = tp.getThrowableDataPointArray();
+ cpdc.calculate(tdpArray);
+ verify(tdpArray);
+ }
+
+ @Test
+ public void nested() throws Exception {
+ Throwable t = TeztHelper.makeNestedException(3);
+ ThrowableProxy tp = new ThrowableProxy(t);
+ ClassPackagingDataCalculator cpdc = tp.getClassPackagingDataCalculator();
+ ThrowableDataPoint[] tdpArray = tp.getThrowableDataPointArray();
+ cpdc.calculate(tdpArray);
+ verify(tdpArray);
+ }
+
+ public void doCalculateClassPackagingData(
+ boolean withClassPackagingCalculation) {
+ try {
+ throw new Exception("testing");
+ } catch (Throwable e) {
+ ThrowableProxy tp = new ThrowableProxy(e);
+ if (withClassPackagingCalculation) {
+ tp.getClassPackagingDataCalculator();
+ ClassPackagingDataCalculator cpdc = tp
+ .getClassPackagingDataCalculator();
+ ThrowableDataPoint[] tdpArray = tp.getThrowableDataPointArray();
+ cpdc.calculate(tdpArray);
+ }
+ }
+ }
+
+ double loop(int len, boolean withClassPackagingCalculation) {
+ long start = System.nanoTime();
+ for (int i = 0; i < len; i++) {
+ doCalculateClassPackagingData(withClassPackagingCalculation);
+ }
+ return (1.0 * System.nanoTime() - start) / len / 1000;
+ }
+
+ @Test
+ public void perfTest() {
+ int len = 500;
+ loop(len, false);
+ loop(len, true);
+
+ double d0 = loop(len, false);
+ System.out.println("without packaging info " + d0 + " microseconds");
+
+ double d1 = loop(len, true);
+ System.out.println("with packaging info " + d1 + " microseconds");
+ assertTrue("computing class packaging data (" + d1
+ + ") should have been less than six times the time it takes to process an exception" + (d0 * 6),
+ d0 * 6 > d1);
+ }
+}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,11 @@
+package ch.qos.logback.classic.spi;
+
+public interface CPDCSpecial {
+
+ public abstract void doTest();
+
+ public abstract Throwable getThrowable();
+
+ public abstract ThrowableProxy getThrowableProxy();
+
+}
\ No newline at end of file
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,66 @@
+package ch.qos.logback.classic.spi;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * An almost trivial no fuss implementation of a class loader following the
+ * child-first delegation model.
+ *
+ * @author Ceki Gülcü
+ */
+public class LocalFirstClassLoader extends URLClassLoader {
+
+ public LocalFirstClassLoader(URL[] urls) {
+ super(urls);
+ }
+
+ public LocalFirstClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
+
+ public void addURL(URL url) {
+ super.addURL(url);
+ }
+
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ return loadClass(name, false);
+ }
+
+ /**
+ * We override the parent-first behavior established by java.lang.Classloader.
+ *
+ * The implementation is surprisingly straightforward.
+ */
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+
+ // First, check if the class has already been loaded
+ Class c = findLoadedClass(name);
+
+ // if not loaded, search the local (child) resources
+ if (c == null) {
+ try {
+ c = findClass(name);
+ } catch (ClassNotFoundException cnfe) {
+ // ignore
+ }
+ }
+
+ // if we could not find it, delegate to parent
+ // Note that we don't attempt to catch any ClassNotFoundException
+ if (c == null) {
+ if (getParent() != null) {
+ c = getParent().loadClass(name);
+ } else {
+ c = getSystemClassLoader().loadClass(name);
+ }
+ }
+
+ if (resolve) {
+ resolveClass(c);
+ }
+
+ return c;
+ }
+}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java Mon Sep 8 17:42:48 2008
@@ -24,6 +24,7 @@
suite.addTest(new JUnit4TestAdapter (LoggerComparatorTest.class));
suite.addTest(new JUnit4TestAdapter (LoggingEventSerializationTest.class));
suite.addTest(new JUnit4TestAdapter(ch.qos.logback.classic.spi.ThrowableToDataPointTest.class));
+ suite.addTest(new JUnit4TestAdapter(ch.qos.logback.classic.spi.BasicCPDCTest.class));
return suite;
}
}
\ No newline at end of file
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,31 @@
+package ch.qos.logback.classic.spi.special;
+
+import ch.qos.logback.classic.spi.CPDCSpecial;
+import ch.qos.logback.classic.spi.ClassPackagingDataCalculator;
+import ch.qos.logback.classic.spi.ThrowableProxy;
+
+
+public class CPDCSpecialImpl implements CPDCSpecial {
+
+
+ Throwable throwable;
+ ThrowableProxy throwableProxy;
+
+ public void doTest() {
+ nesting();
+ }
+
+ private void nesting() {
+ throwable = new Throwable("x");
+ throwableProxy = new ThrowableProxy(throwable);
+ ClassPackagingDataCalculator cpdc = new ClassPackagingDataCalculator();
+ cpdc.calculate(throwableProxy.getThrowableDataPointArray());
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+ public ThrowableProxy getThrowableProxy() {
+ return throwableProxy;
+ }
+}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,13 @@
+package ch.qos.logback.classic.util;
+
+public class TeztHelper {
+
+
+ static public Throwable makeNestedException(int level) {
+ if (level == 0) {
+ return new Exception("nesting level=" + level);
+ }
+ Throwable cause = makeNestedException(level - 1);
+ return new Exception("nesting level =" + level, cause);
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java Mon Sep 8 17:42:48 2008
@@ -0,0 +1,9 @@
+package ch.qos.logback.core.util;
+
+public class SystemInfo {
+
+
+ public static String getJavaVendor() {
+ return OptionHelper.getSystemProperty("java.vendor", null);
+ }
+}
More information about the logback-dev
mailing list