Issue232462

classification
Title: jython invokes interface "method" instead actual method
Type: Severity: normal
Components: Core Versions:
Milestone:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: bckfnn, ianzsk
Priority: normal Keywords:

Created on 2001-02-15.03:27:18 by ianzsk, last changed 2001-02-16.18:11:01 by bckfnn.

Messages
msg282 (view) Author: ian west (ianzsk) Date: 2001-02-15.03:27:18
This bug seems similar to(but not the same as) bug #122847 

Given the following Java code:
//-----------------------------
package aa;
interface Named {
	String getName();
}
public class bug implements Named {
	public bug() {}
	public String  getName() { return "name"; }

}
//--------
The following jython (Jython 2.0 on java1.3.0 (JIT: null)) script invokes an IllegalAccessException
#!/usr/bin/env jython
from aa import bug
b=bug()
b.getName()
# same problem with bean property : b.name


Possible resolution:
----------------------------
Assuming that creating PyJavaClass Objects for interfaces is a requirement for
jython to work properly (!), the short circuit in 
PyJavaClass.addPropery() method viz:

// If this adds nothing over old property, do nothing
 if ((prop.getMethod == null || oldProp.getMethod != null)
 &&
(prop.setMethod == null || oldProp.setMethod != null))


should be replace with:

boolean nogetOverride=(oldProp.getMethod != null &&
                        !Modifier.isAbstract(oldProp.getMethod.getModifiers()) );
boolean nosetOverride =(oldProp.setMethod != null &&
                        !Modifier.isAbstract(oldProp.setMethod.getModifiers()) );
 if ((prop.getMethod == null || nogetOverride )
                        &&
  (prop.setMethod == null || nogetOverride ) )
                    {
                        set = false;
                    }

  // Add old get/set methods to current prop
 // Handles issues with private classes
 if (nogetOverride) {
      prop.getMethod = oldProp.getMethod;
}
 if (nosetOverride) {
      prop.setMethod = oldProp.setMethod;
}


i.e. override if it is abstract.


I also changed the code at the bottom of ReflectedArgs.compareTo() method to:

// For static methods, use the child's version
 // For instance methods, use the parent's version
 if (!isStatic && ( other.declaringClass.getModifiers() & (Modifier.INTERFACE))==0 ) replace = !replace;


These two changes at least fix the problem above, but are not maybe the most general solution. 
msg283 (view) Author: ian west (ianzsk) Date: 2001-02-16.06:58:10
OK, OK forget all of  the above "fixes".  this bug is the same type of bug
as demonstrated in BUG#122847
my workaround is to add  a method  to PyJavaClass (see below) that returns only the public interfaces of a class;  and then change __init_bases to:

Class[] interfaces=getAccessibleInterfaces(c);


This fixes up the problem above. Similar alteratertions to 
getAccessibleMethods(), getAccessibleFields() and getAccessibleConstructors()
in PyJavaClass fixes BUG#122847

//----
private static Class[] filterPublic(Class[] in) {
        java.util.Vector v=new java.util.Vector();
        for(int i=0;i<in.length;i++) {
          if(!Modifier.isPublic(in[i].getModifiers())) continue;
          v.addElement(in[i]);
        }
        if(v.size()==in.length) return in;
        Class[] ret = new Class[v.size()];
        v.copyInto(ret);
        return ret;
    }
    private static Class[] getAccessibleInterfaces(Class c) {
      // can't modify accessibility of interfaces in Java2
      // thus get only public interfaces
        return filterPublic(c.getInterfaces());

    }
msg284 (view) Author: Finn Bock (bckfnn) Date: 2001-02-16.18:11:01
Fixed in PyJavaClass.java: 2.33;
History
Date User Action Args
2001-02-15 03:27:18ianzskcreate