@CallerSensitive as public API ?

Mandy Chung mandy.chung at oracle.com
Mon Jul 22 09:08:32 UTC 2013

Hi Peter,

I have been very busy on other high priority works and didn't have time 
to look into this request.  I filed 8020968 and 8020785 so that others 
can help follow up and follow up (I'll be on vacation this Wed).

Class.getCallerClass and @CallerSensitive is clearly one option to 
replace sun.reflect.Reflection.getCallerClass.  I'm not precluding this 
option at all.  This would require further investigation and it's not a 
small task that includes spec work (might have impact to JVM spec), 
whether implementable by all Java SE implementation, JCK tests, security 
and there will be subtle issues to consider when defining the 
specification etc.  It seems that this option requires more work than 
what we can take in jdk8.

For your specific use case, the other option we can explore to satisfy 
your use case is to define a static method to use the caller's class to 
find the resources.  You guessed what I have in mind.  Take your example 
you use below,  if the stack looks like this:


Class.getCallerResource(String name) will be equivalent to calling:
     Class<?> caller = sun.reflect.Reflection.getCallerClass();

I'll need to find if there is anyone who can help look into these 
options.  Your help and contribution is very welcome.


On 7/22/2013 2:57 AM, Peter Levart wrote:
> Hi Mandy,
> I wonder what API you had in mind. Currently we have ClassLoader and 
> Class instance methods to load resources which are quite low-level in 
> the sense that they require full or relative path to the resource and 
> they return either URL or InputStream. So they usually get wrapped by 
> utilities implementing special search strategies and/or resource 
> un-marshaling.
> For example, imagine one would like to locate resource using the 
> caller class' ClassLoader using the resource path composed of the 
> package name of the caller class replacing dots with slashes and 
> specified resource name appended, then load the content of the 
> resource into a BufferedImage and construct an Icon from it, wrapping 
> any IOException thrown with some unchecked exception:
> package my.pkg;
> class MyClass {
> void someMethod() {
>     // a static utility method:
>     Icon saveIcon = Resources.getIcon("save-icon.png");
>     // that does the following:
>     Icon saveIcon;
>     try {
>         saveIcon = new 
> ImageIcon(ImageIO.read(MyClass.class.getResource("save-icon.png")));
>     } catch (IOException e) {
>         throw new RuntimeException(e);
>     }
> I don't suggest creating such APIs in the JDK, just enabling them. So 
> what would it take for an API in ClassLoader or Class to enable 
> creating an API like Resources.getIcon() presented above?
> I guess a static method like Class.getCallerClass() would do, but I 
> have a feeling this is something that is flagged as sensitive by the 
> security team, right?
> So what about Class.getCallerClassResource(String name)? This would 
> not locate the resource on behalf of the directly calling class, but 
> the class that is calling some method that is calling this method.
> Regards, Peter
> P.S. I still don't know why would method like Class.getCallerClass() 
> be so security sensitive? In order for the getCallerClass() to succeed 
> the method calling it would have to be annotated with @CallerSensitive 
> annotation. If a method has such annotation, anyone deciding to call 
> such method is warned in advance that this method is "extracting" the 
> callers class and using it as it finds fit. There's no danger of 
> untrusted code to sneak it's own @CallerSensitive methods so that 
> unaware code calls them or is it? Does @CallerSensitive work on 
> statically resolved methods or on runtime resolved methods? I mean, if 
> there is some code in some security-sensitive class:
> Runnable r = ....
> r.run();
> // where a Runnable instance is provided by untrusted code:
> class EvilRunnable implements Runnable {
>     @Override
>     @CallerSensitive
>     public void run() {
>         Class<?> caller = Class.getCallerClass();
>         // do some things with caller....
>     }
> }
> Would @CallerSensitive have desired effect as it is implemented 
> currently or would it work only if Runnable.run() interface method was 
> annotated?
>> On 6/25/2013 6:50 PM, 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