To be able to better judge the risk of reflection while porting to Java 9 I wonder if shallow reflection in place of static compilation is safe as long as it references a accessible type:
I mean, can I always replace
PublicType p = (PublicType)(Factory.instance());
p.publicMethod();
(Where Factory.instance()
has return type Object
and will return an subtype of the API type (Package.PublicType
) from a module which is not open).
with
Object p = Factory.instance();
Class<?> c = Class.forName("package.PublicType");
Method m = c.getMethod("publicMethod", (Class[])null);
// assert p instanceof package.PublicType
m.invoke(p, (Object[])null); // throws?
Earlier versions of this question where about a specific code problem which I have resolved meanwhile.
But the general question is interesting to discuss as well: Are there cases where a returned object is of the correct subtype but fails the access checks while invoke or MethodHandle resolve.
Class.forName("package.PublicType")
is guaranteed to resolve to the same aspackage.PublicType.class
, i.e. identical to static resolution. So as long aspackage.PublicType
is an accessible type, using shallow reflection through itsClass
object should work, regardless of whether the instance has a non-exported subtype. But I didn’t check the specification for additional pitfalls. – Nainsook--add-opens
". It's just hard to parse the question when some of the interesting pieces of information are hidden behind "more comments", particularly when it is not clear whether these information are relevant or not. – OvertimeMethod
object, not the type of the instance. Therefore, your exception indicates that you did usecom.sun.jnlp.BasicServiceImpl
for looking up the method, rather than the exported public type, asClass.forName("javax.jnlp.BasicService").getMethod(…)
can’t returnMethod
objects with a declaring class ofcom.sun.jnlp.BasicServiceImpl
. – Nainsook