Author jeff.allen
Recipients jeff.allen, zyasoft
Date 2018-04-05.20:07:58
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
I have a couple of ideas that involve going up the inheritance chain (MRO) from the actual class of the target object to find a method with the same signature that is amenable to a reflective invocation at run-time. THese botyh depend on the behaviour that Method.invoke promises: that where the target method is overidden in the actual class of the target object, the overriding definition is used.

In one idea we go up the MRO until we find the "most senior" definition of the required method, which is assumed to be the public API.

In the second, we go up until we find one where trySetAccessible succeeds.

See attached toy. I prefer the first of these because it works in all versions of Java. I think the place to do it is where the PyReflectedFunction is being created, not during the call itself. However, we would do this for all Java classes, and it so change the contents of the type object significantly. I'm unclear about what malign consequences may follow. A good consequence would be fewer PyReflectedFunction/Method objects. I haven't tried this yet, but the effect can be simulated  like this:

PS jython-jvm9> dist\bin\jython -J--illegal-access=deny
>>> import java.nio.charset.Charset as Charset
>>> import java.nio.CharBuffer as CharBuffer
>>> gbk = Charset.forName('gbk')
>>> type(gbk)
<type 'sun.nio.cs.GBK'>
>>> enc = gbk.newEncoder()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
        at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(
        at java.base/java.lang.reflect.AccessibleObject.checkAccess(
        at java.base/java.lang.reflect.Method.invoke(
java.lang.IllegalAccessException: java.lang.IllegalAccessException: class org.python.core.PyReflectedFunction cannot access class sun.nio.cs.GBK (in module java.base) because module java.base does not export sun.nio.cs to unnamed module @2a7ed1f

But if we get the (abstract) Charset.newEncoder method, that works:

>>> ne = Charset.__dict__['newEncoder']
>>> ne
<java function newEncoder 0x3>
>>> enc = ne(gbk)
>>> enc.encode(CharBuffer.wrap(u"hello"))
java.nio.HeapByteBuffer[pos=0 lim=5 cap=10]
Date User Action Args
2018-04-05 20:08:00jeff.allensetmessageid: <>
2018-04-05 20:08:00jeff.allensetrecipients: + jeff.allen, zyasoft
2018-04-05 20:08:00jeff.allenlinkissue2662 messages
2018-04-05 20:07:59jeff.allencreate