Using java.awt.Toolkit.getDefaultToolkit().getScreenSize() reflectively causes InaccessibleObjectException

Peter Levart peter.levart at gmail.com
Fri Jan 6 22:22:09 UTC 2017


Hi Rony,

On 01/06/2017 02:28 PM, Rony G. Flatscher wrote:
>> >The j.l.r.Method object on which you call invoke() should not be obtained by inspecting the
>> >methods of the implementation class given by getDefaultToolkit().getClass(). Implementation
>> >classes (i.e. classes in non-exported packages) cannot be instantiated, nor their members
>> >manipulated, by code outside their module.
>> >
>> >The j.l.r.Method object on which you call invoke() should be obtained by inspecting the methods of
>> >the "public Java class" java.awt.Toolkit. The first argument that you pass to invoke(), indicating
>> >the receiver, can still be instanceof the implementation class.
> As was noted earlier, the information that some Java object xyz was created by some public method
> "getDefaultToolkit()" and hence knowing that its return type would be that of the java.desktop
> public class java.awt.Toolkit is not available at runtime.

But it is. The method Toolkit.getDefaultToolkit() has a return type. You 
can use reflection to find out that return type of that method:

Method getDefKitMeth = Toolkit.class.getMethod("getDefaultToolkit");
Class<?> tkClass = getDefKitMeth.getReturnType();

// now you can obtain the toolkit instance:
Object tkInst = getDefKitMeth.invoke(null);

// and obtain a method to be called upon it
Method getScrSizMeth = tkClass.getMethod("getScreenSize");

// and invoke it:
Object screenSize = getScrSizMeth.invoke(tkInst);

... and so on...


You see, I never had to mention java.awt.Toolkit type explicitly to 
invoke getScreenSize on an object of that type (or subtype). If you 
think what a programmer does when he codes this in straight Java without 
using reflection, it is the following:

1. He finds out a factory method on Toolkit class: 
Toolkit.getDefaultToolkit()
2. He looks up the return type of that method (in javadocs).
3. He uses that type to declare a local variable to which it assigns the 
result of the method invocation:

java.awt.Toolkit tkInst = java.awt.Toolkit.getDefaultToolkit();

4. He looks up and finds an instance method to call in type 
java.awt.Toolkit: java.awt.Toolkit.getScreenSize() and writes it down:

tkInst.getScreenSize();

Above invocation is using static type java.awt.Toolkit - the return type 
of Toolkit.getDefaultToolkit().

You can do similar things with reflection. Instead of using 
anInstance.getClass() to get the runtime class of the instance, you can 
use Method.getReturnType() of the method that was used to obtain the 
instance. If API is designed so that no casts are needed when you chain 
calls, then this should work.


Regards, Peter



More information about the jigsaw-dev mailing list