You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/10/08 06:00:27 UTC

[3/7] git commit: Add getCallerClass(Class) method.

Add getCallerClass(Class) method.

  - Can be used when the FQCN is known in advance and is an
  accessible class at compile time.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/47547e07
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/47547e07
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/47547e07

Branch: refs/heads/master
Commit: 47547e0742105d155a375697e73db74da7c73994
Parents: 5b3887b
Author: Matt Sicker <ma...@apache.org>
Authored: Tue Oct 7 22:51:00 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Tue Oct 7 22:51:00 2014 -0500

----------------------------------------------------------------------
 .../logging/log4j/util/ReflectionUtil.java      | 75 +++++++++++++++++---
 .../logging/log4j/util/ReflectionUtilTest.java  | 10 +++
 2 files changed, 74 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/47547e07/log4j-api/src/main/java/org/apache/logging/log4j/util/ReflectionUtil.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/ReflectionUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/ReflectionUtil.java
index ad707c7..128045d 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/ReflectionUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/ReflectionUtil.java
@@ -108,6 +108,9 @@ public final class ReflectionUtil {
         return SUN_REFLECTION_SUPPORTED;
     }
 
+    // TODO: return Object.class instead of null (though it will have a null ClassLoader)
+    // (MS) I believe this would work without any modifications elsewhere, but I could be wrong
+
     // migrated from ReflectiveCallerClassUtility
     public static Class<?> getCallerClass(final int depth) {
         if (depth < 0) {
@@ -121,6 +124,7 @@ public final class ReflectionUtil {
             } catch (final Exception e) {
                 // theoretically this could happen if the caller class were native code
                 LOGGER.error("Error in ReflectionUtil.getCallerClass({}).", depth, e);
+                // TODO: return Object.class
                 return null;
             }
         }
@@ -132,6 +136,7 @@ public final class ReflectionUtil {
         } catch (final ClassNotFoundException e) {
             LOGGER.error("Could not find class in ReflectionUtil.getCallerClass({}).", depth, e);
         }
+        // TODO: return Object.class
         return null;
     }
 
@@ -185,7 +190,7 @@ public final class ReflectionUtil {
 
     // migrated from ClassLoaderContextSelector
     public static Class<?> getCallerClass(final String fqcn) {
-        return getCallerClass(fqcn, "");
+        return getCallerClass(fqcn, Strings.EMPTY);
     }
 
     // migrated from Log4jLoggerFactory
@@ -202,28 +207,62 @@ public final class ReflectionUtil {
                     return clazz;
                 }
             }
+            // TODO: return Object.class
             return null;
         }
         if (SECURITY_MANAGER != null) {
             return SECURITY_MANAGER.getCallerClass(fqcn, pkg);
         }
-        boolean next = false;
-        final StackTraceElement[] elements = new Throwable().getStackTrace();
         try {
-            for (final StackTraceElement element : elements) {
-                final String className = element.getClassName();
-                if (className.equals(fqcn)) {
+            return LoaderUtil.loadClass(getCallerClassName(fqcn, pkg, new Throwable().getStackTrace()));
+        } catch (final ClassNotFoundException ignored) {
+            // no problem really
+        }
+        // TODO: return Object.class
+        return null;
+    }
+
+    // added for use in LoggerAdapter implementations mainly
+    public static Class<?> getCallerClass(final Class<?> anchor) {
+        if (supportsFastReflection()) {
+            boolean next = false;
+            Class<?> clazz;
+            for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
+                if (anchor.equals(clazz)) {
                     next = true;
                     continue;
                 }
-                if (next && className.startsWith(pkg)) {
-                    return LoaderUtil.loadClass(className);
+                if (next) {
+                    return clazz;
                 }
             }
+            return Object.class;
+        }
+        if (SECURITY_MANAGER != null) {
+            return SECURITY_MANAGER.getCallerClass(anchor);
+        }
+        try {
+            return LoaderUtil.loadClass(getCallerClassName(anchor.getName(), Strings.EMPTY,
+                new Throwable().getStackTrace()));
         } catch (final ClassNotFoundException ignored) {
             // no problem really
         }
-        return null;
+        return Object.class;
+    }
+
+    private static String getCallerClassName(final String fqcn, final String pkg, final StackTraceElement... elements) {
+        boolean next = false;
+        for (final StackTraceElement element : elements) {
+            final String className = element.getClassName();
+            if (className.equals(fqcn)) {
+                next = true;
+                continue;
+            }
+            if (next && className.startsWith(pkg)) {
+                return className;
+            }
+        }
+        return Object.class.getName();
     }
 
     // migrated from ThrowableProxy
@@ -258,9 +297,8 @@ public final class ReflectionUtil {
         }
 
         protected Class<?> getCallerClass(final String fqcn, final String pkg) {
-            final Class<?>[] classes = getClassContext();
             boolean next = false;
-            for (final Class<?> clazz : classes) {
+            for (final Class<?> clazz : getClassContext()) {
                 if (fqcn.equals(clazz.getName())) {
                     next = true;
                     continue;
@@ -269,9 +307,24 @@ public final class ReflectionUtil {
                     return clazz;
                 }
             }
+            // TODO: return Object.class
             return null;
         }
 
+        protected Class<?> getCallerClass(final Class<?> anchor) {
+            boolean next = false;
+            for (final Class<?> clazz : getClassContext()) {
+                if (anchor.equals(clazz)) {
+                    next = true;
+                    continue;
+                }
+                if (next) {
+                    return clazz;
+                }
+            }
+            return Object.class;
+        }
+
     }
 
     private ReflectionUtil() {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/47547e07/log4j-api/src/test/java/org/apache/logging/log4j/util/ReflectionUtilTest.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/ReflectionUtilTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/ReflectionUtilTest.java
index 0a482bb..782dc72 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/ReflectionUtilTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/ReflectionUtilTest.java
@@ -21,6 +21,7 @@ import java.util.Stack;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.ParentRunner;
 import sun.reflect.Reflection;
 
 import static org.junit.Assert.*;
@@ -93,4 +94,13 @@ public class ReflectionUtilTest {
         // update this test accordingly
         assertSame(expected, actual);
     }
+
+    @Test
+    public void testGetCallerClassViaAnchorClass() throws Exception {
+        final Class<?> expected = BlockJUnit4ClassRunner.class;
+        final Class<?> actual = ReflectionUtil.getCallerClass(ParentRunner.class);
+        // if this test fails in the future, it's probably because of a JUnit upgrade; check the new stack trace and
+        // update this test accordingly
+        assertSame(expected, actual);
+    }
 }