Issue1785

classification
Title: No exception thrown when calling not-implemented Java interface method
Type: behaviour Severity: normal
Components: None Versions: Jython 2.7, Jython 2.5
process
Status: open Resolution: remind
Dependencies: Superseder:
Assigned To: fwierzbicki Nosy List: dominik, fwierzbicki, richardfearn
Priority: high Keywords: patch

Created on 2011-07-31.17:46:40 by dominik, last changed 2014-06-18.17:54:37 by zyasoft.

Files
File name Uploaded Description Edit Remove
notimplemented.patch richardfearn, 2011-08-24.19:20:53 Patch so that proxies throw an error if an abstract method is called
Messages
msg6592 (view) Author: Dominik Roblek (dominik) Date: 2011-07-31.17:46:39
I have a Java interface:
---
public interface JavaInterface {
    Object add(Object a, Object b);
    void multiply(Object a, Object b);
}
---

I also have a Jython implementation which implements only the "add" method, but not the "multiply" method:
---
class JythonImpl(JavaInterface):

    def __init__ (self):
        pass

    def add(self, a, b):
        return a + b

if __name__ == "__main__":
    jythonClass = JythonImpl()
    try:
        print jythonClass.multiply(10, 20)
    except Exception, e:
        print e
---

The 'jythonClass.multiply(10, 20)' statement above should throw an 'abstract method "multiply" not implemented' exception, but it doesn't when using Jython 2.5.*. Instead it returns None.

The old Jython 2.2.1 did throw the mentioned exception in such case.
msg6611 (view) Author: Richard Fearn (richardfearn) Date: 2011-08-24.19:20:52
Dominik is right - 2.2.1 did throw an AttributeError, but 2.5.* doesn't.

This seems to be due to a change in org.python.compiler.ProxyMaker.

When ProxyMaker adds a method to the proxy class it is building (in its addMethod method), it knows when the method is abstract.

In 2.2.1, the proxy called Py.jgetattr, which would end up throwing the AttributeError.

In 2.5.*, the proxy calls ProxyMaker.findPython to get, from the underlying PyObjectDerived object, the attribute that corresponds to the invoked method's name. Since that attribute is not set on the object (i.e. the method is not overridden), it gets back the PyMethod corresponding to the proxy method currently being invoked. But it recognises this, and returns null. Since the proxy then has no method to invoke, it skips over the code generated by callMethod, to the code generated by doNullReturn - which returns a zero/false/null value, as appropriate for the return type of the method being invoked.

So the end result of this is that the proxy knows the method is abstract, knows it hasn't been overridden by the object, but returns zero/false/null.

Adding this before the doNullReturn call:

    throwNotImplementedException(code, name);

and adding these two methods to ProxyMaker:

    protected static void throwNotImplementedException(Code code, String name) {
        code.ldc(name);
        code.invokestatic("org/python/compiler/ProxyMaker", "throwNotImplementedException", "(Ljava/lang/String;)V");
    }

    public static void throwNotImplementedException(String name) throws PyException {
        String msg = "abstract method \"" + name + "\" not implemented";
        throw new PyException(Py.AttributeError, new PyString(msg));
    }

seems to work. Patch attached.

(Disclaimer: not extensively tested, I'm not a Jython developer, etc. etc.)
msg7693 (view) Author: Richard Fearn (richardfearn) Date: 2013-02-18.15:00:40
This is still an issue with 2.7 b1.
msg7694 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2013-02-19.16:42:28
Hi Richard, I'm trying to clean up our versions. I plan to retire all of the alpha, beta, and rc designations and switch to simple version numbers as CPython does on their tracker. This one is changed only because it was new and I was testing the new version scheme. Also I upped the priority to grab my attention as I triage our outstanding bugs. Thanks!
msg7696 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2013-02-19.16:43:47
Correction - not "new" but had my attention at the same time that I was working on the tracker :)
History
Date User Action Args
2014-06-18 17:54:37zyasoftsetresolution: remind
2013-02-19 16:43:47fwierzbickisetmessages: + msg7696
2013-02-19 16:43:18fwierzbickisetmessages: - msg7695
2013-02-19 16:43:00fwierzbickisetmessages: + msg7695
2013-02-19 16:42:29fwierzbickisetmessages: + msg7694
2013-02-19 05:47:54fwierzbickisetpriority: normal -> high
2013-02-19 05:47:07fwierzbickisetversions: + Jython 2.5, Jython 2.7, - 2.5b0, 2.5.1, 2.5b1, 2.5.0, 2.5.2b1, 2.5.2rc, 2.5.2
2013-02-18 15:00:41richardfearnsetmessages: + msg7693
2012-08-10 21:14:43fwierzbickisetpriority: normal
assignee: fwierzbicki
nosy: + fwierzbicki
2011-08-24 19:20:53richardfearnsetfiles: + notimplemented.patch
keywords: + patch
messages: + msg6611
2011-08-24 15:10:46richardfearnsetnosy: + richardfearn
2011-07-31 17:46:40dominikcreate