Issue1234
Created on 2009-01-13.01:22:07 by marcdownie, last changed 2009-01-26.02:21:53 by cgroves.
Messages | |||
---|---|---|---|
msg4037 (view) | Author: Marc Downie (marcdownie) | Date: 2009-01-13.01:22:05 | |
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. |
|||
msg4078 (view) | Author: Charlie Groves (cgroves) | Date: 2009-01-26.02:21:52 | |
Should be fixed as of r5981: Jython 2.5b1+ (trunk:5978:5979M, Jan 25 2009, 18:08: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 >>> AImpl.__mro__ (<type 'somepackage.AImpl'>, <type 'somepackage.A'>, <type 'somepackage.B'>, <type 'java.lang.Object'>, <type 'object'>) >>> from somepackage import B >>> B.C.__mro__ (<type 'somepackage.B$C'>, <type 'somepackage.A'>, <type 'somepackage.B$D'>, <type 'somepackage.B'>, <type 'java.lang.Object'>, <type 'object'>) >>> |
History | |||
---|---|---|---|
Date | User | Action | Args |
2009-01-26 02:21:53 | cgroves | set | status: open -> closed resolution: fixed messages: + msg4078 nosy: + cgroves |
2009-01-13 01:22:08 | marcdownie | create |
Supported by Python Software Foundation,
Powered by Roundup