@CallerSensitive as public API ? (original) (raw)

Dr Heinz M. Kabutz heinz at javaspecialists.eu
Wed Jun 26 01:10:51 UTC 2013


Hi Peter,

here is another use case, where someone might want to use this:

3 - in a static context, find out what the class is that you are in.

For example, if you want to create a logger, instead of doing this:

private static final Logger log = Logger.getLogger(SomeClass.class);

we could instead have a magic method that figures out what class this is being called from and then sets the class automatically.

There are two other ways to do this, but they are a lot slower than Reflection.getCallerClass():

  1. http://www.javaspecialists.eu/archive/Issue137.html - create an exception and figure out who the calling class is

  2. Or we can use the SecurityManager to get us a stack of contexts.

For example, in the exercises for my courses, some students had problems with the JUnit plugin. So each test case also contains the main method, but it is always the same:

public static void main(String[] args) {
    UnitTestRunner.run();
}

My UnitTestRunner then depends on the security manager to decide what the actual class is and then uses the JUnit4TestAdapter to call the methods:

import junit.framework.; import junit.textui.;

public class UnitTestRunner { private static void run(Class clazz) { System.out.println("Running unit tests for " + clazz); TestRunner.run(new JUnit4TestAdapter(clazz)); }

public static void run() {
    MySecurityManager sm = new MySecurityManager();
    Class clazz = sm.getClassContext()[2];
    run(clazz);
}

private static class MySecurityManager extends SecurityManager {
    public Class[] getClassContext() {
        return super.getClassContext();
    }
}

}

Works like a charm. Fortunately this is not affected by the Reflection.getCallerClass() bug.

Just my 2c :-)

Regards

Heinz

Dr Heinz M. Kabutz (PhD CompSci) Author of "The Java(tm) Specialists' Newsletter" Oracle Java Champion 2005-2013 JavaOne Rock Star Speaker 2012 http://www.javaspecialists.eu Tel: +30 69 75 595 262 Skype: kabutz

Peter Levart wrote:

Hi,

I know that @CallerSensitive annotation was introduced to bring some order to JDK internal plumbings. It's scope was to support JDK internal usage, so it's use is limited to classes loaded by bootstrap or extension class-loaders. In JDK-internal code it is used mainly for implementing security-sensitive decisions. But since the sun.reflect.Reflection.getCallerClass(int) was public and unrestricted, it found it's way out into user code, where at least I know that it is used in two areas: 1 - to locate callers in the whole call-stack so that their location in class-path can be reported (Log4J is an example) 2 - to locate immediate caller so that some resources associated with it can be located and used (for example localization data in GUI applications) I don't know how wide-spread 1st usecase is, but the 2nd is common, since it's use enables APIs that need not explicitly pass-in the calling class in order to locate resources associated with it (and/or the class-loader of it). So it would be nice to have such supported API in JDK8 at least. I'm asking here, to hear any arguments against making such API supported and public. Are there any security or other issues? If there aren't, what steps should be taken to introduce such API in the JDK8 timeframe? I'm thinking of a no-arg method, say j.l.Class.getCaller() and moving @CallerSensitive to a supported package + enabling it to mark methods in any class (not just system and ext classes)... Regards, Peter



More information about the core-libs-dev mailing list