@CallerSensitive as public API ?

Dr Heinz M. Kabutz heinz at javaspecialists.eu
Wed Jun 26 09:40:24 UTC 2013



Remi Forax wrote:
> On 06/26/2013 03:10 AM, Dr Heinz M. Kabutz wrote:
>> 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
>
> Hi Heinz,
> You can also use the JSR 292 Lookup object
>   MethodHandles.lookup().lookupClass()
>
Brilliant, thanks Rémi!  I've learned something new :-)

However, in this case it would not work as I need to find the calling 
class, not the UnitTestRunner class.  Is there a way to find out which 
class called you with MethodHandles?

Heinz



More information about the core-libs-dev mailing list