Message10234

Author jsaiz
Recipients jsaiz
Date 2015-09-09.16:03:57
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1441814639.01.0.138245322898.issue2391@psf.upfronthosting.co.za>
In-reply-to
Content
[DESCRIPTION]

Consider this Java interface:

package attributeTest;
public interface NumberHolder {
    Number getNumber();
}

And this class implementing it:

package attributeTest;
public class DoubleHolder implements NumberHolder {
    private Double number = 0.0;
    @Override public Double getNumber() {
        return number;
    }
    public void setNumber(Double number) {
        this.number = number;
    }
}

Now try to use it from Jython:

> from attributeTest import DoubleHolder
> d = DoubleHolder()
> print d.number
0.0
> d.number = 3.0
<type 'exceptions.AttributeError'>: read-only attr: number

The reported error is wrong, as the DoubleHolder class has actually a setNumber method matching the attribute.


[ANALYSIS]

Digging into the code (Jython 2.5 codebase), this comes from the init method of org.python.core.PyJavaType.

When building the bean properties map, all DoubleHolder's methods are got by means of java.lang.Class.getMethods (line 273).

This returns all methods for the type and its parent classes and interfaces. Thus it gets:

[NumberHolder] Number getNumber()
[DoubleHolder] Double getNumber()
[DoubleHolder] void setNumber(Double)

Class.getMethods does not guarantee any order. What happens is that the getNumber() method of DoubleHolder is processed, then getNumber() of NumberHolder, which overwrites the former, then setNumber().

There is a subsequent check on org.python.core.PyJavaType.init() (lines 488-490) where the getMethod is expected to return the type of the setMethod's argument.

As this is not the case (getNumber returns Number because the interface's method overwrote the one in the class, but setNumber receives a Double), then prop.setMethod is set to null. Which provokes later the mentioned error

<type 'exceptions.AttributeError'>: read-only attr: number


[SOLUTION]

A solution is to sort the props map so that the methods belonging to the class are processed after the methods belonging to super classes or interfaces.

This could be implemented by means of a TreeMap with a comparator ensuring the desired order.

Aside note: this ticket might be related with bug #1610.
History
Date User Action Args
2015-09-09 16:03:59jsaizsetrecipients: + jsaiz
2015-09-09 16:03:59jsaizsetmessageid: <1441814639.01.0.138245322898.issue2391@psf.upfronthosting.co.za>
2015-09-09 16:03:58jsaizlinkissue2391 messages
2015-09-09 16:03:57jsaizcreate