Closed richard-melvin closed 4 years ago
InaccessibleObjectException
was added in JDK 9, which is problematic to use since the codebase is stuck on Java 6.
Hence catching RuntimeException
.
In https://github.com/antlr/stringtemplate4/blob/e38a1c81422317d04908c33dfaa5df6c42753653/src/org/stringtemplate/v4/misc/ObjectModelAdaptor.java#L82 it already treats "any Exception when calling" as "no such property". I think treating "any Exception on method lookup" the same wouldn't be far fetched.
Note that the difference in this case is that just calling the method, without first calling setAccessible, would work.
e,g.
protected static Field tryGetField(Class<?> clazz, String fieldName)
{
try
{
Field field = clazz.getField(fieldName);
if (field != null)
{
try
{
field.setAccessible(true);
}
catch (RuntimeException e)
{
// ignore as it may already be accessible
}
}
return field;
}
catch (NoSuchFieldException | SecurityException ex)
{
// return null to try other options
return null;
}
}
Turns out that is not enough, you actually need something like:
protected static Method tryGetMethod(Class<?> clazz, String methodName)
{
try
{
Method method = clazz.getMethod(methodName);
if (method != null)
{
if (isAccessible(method))
{
return method;
}
for (Class<?> baseInterface : clazz.getInterfaces())
{
Method baseMethod = baseInterface.getMethod(methodName);
if (baseMethod != null && isAccessible(baseMethod))
{
return baseMethod;
}
}
if (clazz.getSuperclass() != null)
{
Method baseMethod = tryGetMethod(clazz.getSuperclass(), methodName);
if (baseMethod != null)
{
return baseMethod;
}
}
}
return null;
}
catch (NoSuchMethodException ex)
{
return null;
}
}
/**
* Access check for method, in a way that is portable to JDK 8 and 9+
* @param method
* @return true if accessible
*/
private static boolean isAccessible(Method method)
{
try
{
method.setAccessible(true);
}
catch (RuntimeException e)
{
return false;
}
return true;
}
Updating my client code to JDK13, a template like:
$if (arguments.empty)$
, where arguments isCollections.unmodifiableList(arguments);
gets an exception
Since JDK9,
Method.setAccessible
can throwInaccessibleObjectException
, which is not caught.This fires in this case because
UnmodifiableCollection
is not a public class, even though the method isEmpty is public and there would be no problem in calling it.I think the code either needs to catch
InaccessibleObjectException
, or maybe justRuntimeException
, or work out how to avoid calling that function when it is not required.