Message4037
Convoluted (but, alas, real world) inheritance hierarchies can cause PyJavaType's
mro computation to NPE.
If we have the following class/interface structure:
package somepackage;
public interface A extends B {}
package somepackage;
public interface B extends B {
public interface C extends A,D {}
public interface D extends B {}
}
package somepackage;
public class AImpl implements A {}
Admittedly this is rather odd, but it's legal Java (at the very least, ecj has
happily compiled something like this for years).
Then, with the appropriate CLASSPATH:
from Jython 2.5b1+ (trunk:5923, Jan 12 2009, 19:12:49)
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_07
Type "help", "copyright", "credits" or "license" for more information.
>>> from somepackage import AImpl
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
java.lang.NullPointerException
at org.python.core.PyJavaType.init(PyJavaType.java:93)
at org.python.core.PyType.createType(PyType.java:990)
at org.python.core.PyType.addFromClass(PyType.java:963)
at org.python.core.PyType.fromClass(PyType.java:1003)
at org.python.core.PyJavaType.init(PyJavaType.java:322)
at org.python.core.PyType.createType(PyType.java:990)
at org.python.core.PyType.addFromClass(PyType.java:963)
at org.python.core.PyType.fromClass(PyType.java:1003)
at org.python.core.PyJavaType.init(PyJavaType.java:87)
at org.python.core.PyType.createType(PyType.java:990)
at org.python.core.PyType.addFromClass(PyType.java:963)
at org.python.core.PyType.fromClass(PyType.java:1003)
at org.python.core.PyJavaType.init(PyJavaType.java:87)
at org.python.core.PyType.createType(PyType.java:990)
at org.python.core.PyType.addFromClass(PyType.java:963)
at org.python.core.PyType.fromClass(PyType.java:1003)
at
org.python.core.adapter.ClassicPyObjectAdapter$6.adapt(ClassicPyObjectAdapter.java:7
6)
at
org.python.core.adapter.ExtensiblePyObjectAdapter.adapt(ExtensiblePyObjectAdapter.ja
va:44)
at
org.python.core.adapter.ClassicPyObjectAdapter.adapt(ClassicPyObjectAdapter.java:120
)
at org.python.core.Py.java2py(Py.java:1481)
at org.python.core.PyJavaPackage.addClass(PyJavaPackage.java:89)
at org.python.core.PyJavaPackage.__findattr_ex__(PyJavaPackage.java:138)
at org.python.core.PyObject.__findattr__(PyObject.java:848)
at org.python.core.imp.import_name(imp.java:706)
at org.python.core.imp.importName(imp.java:741)
at org.python.core.ImportFunction.__call__(__builtin__.java:1265)
at org.python.core.PyObject.__call__(PyObject.java:339)
at org.python.core.__builtin__.__import__(__builtin__.java:1236)
at org.python.core.imp.importFromAs(imp.java:817)
at org.python.core.imp.importFrom(imp.java:794)
at org.python.pycode._pyx2.f$0(<stdin>:1)
at org.python.pycode._pyx2.call_function(<stdin>)
at org.python.core.PyTableCode.call(PyTableCode.java:199)
at org.python.core.PyCode.call(PyCode.java:14)
at org.python.core.Py.runCode(Py.java:1206)
at org.python.core.Py.exec(Py.java:1237)
at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:133)
at
org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:90)
at
org.python.util.InteractiveInterpreter.runsource(InteractiveInterpreter.java:71)
at
org.python.util.InteractiveInterpreter.runsource(InteractiveInterpreter.java:46)
at org.python.util.InteractiveConsole.push(InteractiveConsole.java:110)
at org.python.util.InteractiveConsole.interact(InteractiveConsole.java:90)
at org.python.util.jython.run(jython.java:293)
at org.python.util.jython.main(jython.java:112)
java.lang.NullPointerException: java.lang.NullPointerException
>>>
It's ((PyType)obj).mro that's null on that line.
If I add diagnostics to PyJavaType.init (and avoid the NPE), I can produce this:
>>> from somepackage import AImpl
entering mro init for <somepackage.AImpl>
entering mro init for <somepackage.A>
entering mro init for <somepackage.B>
exiting <somepackage.B> mro is <[Lorg.python.core.PyObject;@3f62e847>
entering mro init for <somepackage.B$C>
entering mro init for <somepackage.B$D>
exiting <somepackage.B$D> mro is <[Lorg.python.core.PyObject;@5dd22889>
WARNING: <somepackage.A> has null mro
exiting <somepackage.B$C> mro is <[Lorg.python.core.PyObject;@40e51e67>
exiting <somepackage.A> mro is <[Lorg.python.core.PyObject;@3107eafc>
exiting <somepackage.AImpl> mro is <[Lorg.python.core.PyObject;@28ee8874>
>>>
You can see that somepackage.A's mro is being used before it has finished computing.
The workaround is simply to take interface C's definition outside B. |
|
Date |
User |
Action |
Args |
2009-01-13 01:22:08 | marcdownie | set | recipients:
+ marcdownie |
2009-01-13 01:22:08 | marcdownie | set | messageid: <1231809728.19.0.469520766525.issue1234@psf.upfronthosting.co.za> |
2009-01-13 01:22:07 | marcdownie | link | issue1234 messages |
2009-01-13 01:22:06 | marcdownie | create | |
|