Issue628315

classification
Title: problem with Java synchronized lists
Type: Severity: normal
Components: None Versions:
Milestone:
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: cgroves, pedronis, trelony, ype
Priority: high Keywords:

Created on 2002-10-24.23:30:43 by anonymous, last changed 2006-08-15.03:49:18 by cgroves.

Files
File name Uploaded Description Edit Remove
test.jy nobody, 2002-10-24.23:30:43 test case script
628315_lookupfix.diff cgroves, 2006-08-12.02:02:47
Messages
msg770 (view) Author: Nobody/Anonymous (nobody) Date: 2002-10-24.23:30:43
Execute attached script. remove(index) throws
IllegalAccessException:

Traceback (innermost last):
  File "test.jy", line 10, in ?
java.lang.IllegalAccessException
        at java.lang.reflect.Method.invoke(Native Method)
        at
org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java)
        at org.python.core.PyMethod.__call__(PyMethod.java)
        at org.python.core.PyObject.__call__(PyObject.java)
        at
org.python.core.PyInstance.invoke(PyInstance.java)
        at org.python.pycode._pyx0.f$0(test.jy:10)
        at org.python.pycode._pyx0.call_function(test.jy)
        at
org.python.core.PyTableCode.call(PyTableCode.java)
        at org.python.core.PyCode.call(PyCode.java)
        at org.python.core.Py.runCode(Py.java)
        at
org.python.core.__builtin__.execfile_flags(__builtin__.java)
        at
org.python.util.PythonInterpreter.execfile(PythonInterpreter.java)
        at org.python.util.jython.main(jython.java)

java.lang.IllegalAccessException:
java.lang.IllegalAccessException
msg771 (view) Author: Ype (ype) Date: 2002-11-16.20:31:39
Logged In: YES 
user_id=125722

This is not a jython bug.
The attached java program gives the following output:

Removed 1 direct
Calling reflected method public java.lang.Object 
java.util.ArrayList.remove(int)
Removed 2 reflected
Removed 3 direct
Calling reflected method public java.lang.Object 
java.util.Collections$SynchronizedList.remove(int)
java.lang.IllegalAccessException class 
java.util.Collections$SynchronizedList remove

Conclusion:

The problem is with java.util.Collections$SynchonizedList
This may be a bug in there.

For completeness: I'm using the following java -version:

java version "1.3.1_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 
1.3.1_04-b02)
Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)

msg772 (view) Author: Samuele Pedroni (pedronis) Date: 2002-11-16.21:09:03
Logged In: YES 
user_id=61408

It is subtler than it seems.

It's Jython fault. When confronted with a non-public class it 
should consider using reflected methods from possibly 
implemented public interfaces and ignore the non-public 
class ones.

[This is part of the things to review about java integration.]

java.util.List.remove(l,0) works indeed.










msg773 (view) Author: Ype (ype) Date: 2002-11-22.19:40:32
Logged In: YES 
user_id=125722

See patch 642483.
msg774 (view) Author: Ype (ype) Date: 2004-05-03.21:30:07
Logged In: YES 
user_id=125722

More general, from Samuele's recent post: 
 
the most clean workaround in 2.1 is to use unbound methods 
out of the  
relevant public interface/class: e.g. 
 
given 
 
public interface I { 
 
   void meth(); 
 
} 
 
and some object obj implenting I but whose concrete class is 
package private: 
 
import I 
 
obj = ... 
 
I.meth(obj) 
 
works.  
 
See also Samuele's comment from Nov 2002. 
msg775 (view) Author: Charlie Groves (cgroves) Date: 2006-08-12.02:02:47
Logged In: YES 
user_id=1174327

The reported exception disappeared between the time this bug
was reported and now.  Interestingly, it's broken in a
different way now.  When you call call remove on a
synchronized list with an int, it calls the remove from
Collection that takes an object instead of the remove from
List that takes an int as the way the Jython java primitive
coercion would make it work normally.  This is because the
synchronized list class doesn't contain the remove method,
and its somewhat convoluted inheritance hierarchy leads
PyJavaClass's lookup to Collection's remove and doesn't
check for remove in other bases. Since the remove(int)
method is in the List interface the wrong method gets called. 

ype's patch 642483 mentioned below has the right idea to fix
this.  It adds all of the methods from the interfaces of the
proxy class to the PyJavaClass directly.  This lets the
superclass handle the method if it can, but if not, it makes
a PyReflectedFunction containing all the relevant argument
variations.  There was a slight but in it though, so I've
attached a fixed version of the patch to this bug.
msg776 (view) Author: Alexey N. Solofnenko (trelony) Date: 2006-08-14.16:01:47
Logged In: YES 
user_id=236600

It is more like a duplicate of 222847 and/or 1331437, than a
Java bug.
msg777 (view) Author: Charlie Groves (cgroves) Date: 2006-08-15.03:49:18
Logged In: YES 
user_id=1174327

So it is.  I just commited r2889 which I think addresses the
base cause by setting the public methods in package
protected classes accessible.  
History
Date User Action Args
2002-10-24 23:30:43anonymouscreate