Using java.awt.Toolkit.getDefaultToolkit().getScreenSize() reflectively causes InaccessibleObjectException
peter.levart at gmail.com
Fri Jan 6 22:22:09 UTC 2017
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:
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:
Above invocation is using static type java.awt.Toolkit - the return type
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.
More information about the jigsaw-dev