Issue663592

classification
Title: Problems calling an overriden class in the constructor
Type: Severity: normal
Components: Core Versions:
Milestone:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: cgroves, gedb, leouserz, nobody
Priority: normal Keywords:

Created on 2003-01-07.10:02:14 by gedb, last changed 2007-04-19.05:20:16 by cgroves.

Messages
msg806 (view) Author: Ged Byrne (gedb) Date: 2003-01-07.10:02:14
I'm having some problems extending an abstract Java 
class.  Everything is fine, except when the extended 
class is called from within the constructor.

First of all is my Abstract Java class.

-----------------------------------------------------------
01 public abstract class Abstract {
02
03    public Abstract() {
04       System.out.println("Java Class Abstract
Constructing");
05       // showInt(5);
06       System.out.println("Java Class Abstract
Constructed");
07    }
08
09    public abstract void showInt(int i);
10
11    public void showSix() {
12       showInt(6);
13    }
10 }
---------------------------------------------
Abstract.java

My Jython script looks like this.
-----------------------------------------------------------
01 import Abstract
02
03 class extends(Abstract):
04
05    def __init__(self):
06       print "Jython class 'extends' initialised"
07
08    def showInt(self, i):
09       print "showInt called with : ", i
10
11
12 x = extends()
13 x.showInt(6)
14 x.showSix()
------------------------------------------------
Extends.jy

The output is as expected:

Jython class 'extends' initialised
Java Class Abstract Constructing
Java Class Abstract Constructed
showInt called with :  6
showInt called with :  6

However, if I decomment line 5 in Abstract.java, so that 
the system attempts to call the abstract method in the 
constructor the output is an error:

Jython class 'extends' initialised
Java Class Abstract Constructing
Traceback (innermost last):
  File "D:\gedbs\Java\lib\uk\co\RushCoding\extend.jy",
line 12, in ?
AttributeError: abstract method "showInt" not
implemented
msg807 (view) Author: Nobody/Anonymous (nobody) Date: 2003-05-09.20:00:26
Logged In: NO 

<A HREF="http://sourceforge.net/tracker/index.php?
func=detail&aid=713373&group_id=12867&atid=112867">713373</A> is a 
repeat of this bug.
msg808 (view) Author: Deleted User leouserz (leouserz) Date: 2007-01-16.16:28:57
It seems that the problem is that the proxy has not been initialised/set yet on the javaproxy.  When a method is accessed in this state, it accesses jgetattr in Py:
    public static PyObject jgetattr(PyProxy proxy, String name) {

        PyInstance o = proxy._getPyInstance();

        PyObject ret = null;

        if (o != null) {

            ret = o.__jfindattr__(name);

        }

        if (ret == null)

            throw Py.AttributeError("abstract method \""+name+

                                    "\" not implemented");

        // Set the current system state to match proxy -- usually this is a

        // waste of time :-(

        Py.setSystemState(proxy._getPySystemState());

        return ret;

    }


Since o, will be null at this point it bombs.  Initialisation happens after the super class constructors have been invoked.  But, in jgetattr's sister method, jfindattr it appears to recognise this as a reality and enforces suitable counter measures:
    public static PyObject jfindattr(PyProxy proxy, String name) {

        PyInstance o = proxy._getPyInstance();

        if (o == null) {

            proxy.__initProxy__(new Object[0]);

            o = proxy._getPyInstance();

        }

        PyObject ret = o.__jfindattr__(name);

        if (ret == null)

            return null;



        // Set the current system state to match proxy -- usually

        // this is a waste of time :-(

        Py.setSystemState(proxy._getPySystemState());

        return ret;

    }


jgetattr is only invoked it appears when the superclass is abstract.  The code generated in ProxyMaker.addMethod.  The patch I am putting together will follow jfindattr in initilising the proxy if its instance is null.  From looking at the test case this allows the method to work in the abstract class.  Also, testing in a class that does not override the abstract method results in the AttributeError(as it should).  Maybe sometime in a future VM spec, having to call the constructor right off the bat will no longer be the rule and we can initialise the proxies first....

leouser
msg809 (view) Author: Deleted User leouserz (leouserz) Date: 2007-01-16.16:35:22
patch for this is here:
http://sourceforge.net/tracker/index.php?func=detail&aid=1636933&group_id=12867&atid=312867

leouser
msg810 (view) Author: Charlie Groves (cgroves) Date: 2007-04-19.05:20:16
Leo's patch committed in r3170.  test396 checks for this raising its ugly head again.
History
Date User Action Args
2003-01-07 10:02:14gedbcreate