Issue222847

classification
Title: Can't acces public member of package private base class
Type: Severity: normal
Components: Core Versions:
Milestone:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: bckfnn, cgroves, ianzsk, jeffsong, mfuzzey, satayboy, szegedia, ype
Priority: low Keywords:

Created on 2000-11-18.19:31:07 by bckfnn, last changed 2006-08-18.02:30:16 by cgroves.

Messages
msg140 (view) Author: Finn Bock (bckfnn) Date: 2000-11-18.19:31:07
For some reason, JPython cannot access a public method that is defined
in the package private base class of my object instance.  public Foo 
extends (package private) Bar.  Bar defines public String hi().  If I 
instantiate Foo and call hi() on the instance, I get an IllegalAccessException.

Java classes:
--------------------------------------------------------------
package testpackage;

public class Foo extends Bar {
}

class Bar {
    public String hi() {
        return "hi";
    }
}
---------------------------------------------------------------

Python code:
---------------------------------------------------------------
>>> from testpackage import Foo
>>> f = Foo()
>>> f.hi()
---------------------------------------------------------------

Resulting exception:
---------------------------------------------------------------
Traceback (innermost last):
  File "<console>", line 1, in ?
java.lang.IllegalAccessException: testpackage/Bar
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:158)
	at org.python.core.PyMethod.__call__(PyMethod.java:66)
	at org.python.core.PyObject.__call__(PyObject.java:260)
	at org.python.core.PyInstance.invoke(PyInstance.java:254)
	at org.python.pycode._pyx5.f$0(<console>)
	at org.python.pycode._pyx5.call_function(<console>)
	at org.python.core.PyTableCode.call(PyTableCode.java:155)
	at org.python.core.Py.runCode(Py.java:937)
	at org.python.core.Py.exec(Py.java:951)
	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:121)
	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:82)
	at org.python.util.InteractiveInterpreter.runsource(InteractiveInterpreter.java:63)
	at org.python.util.InteractiveInterpreter.runsource(InteractiveInterpreter.java:42)
	at org.python.util.InteractiveConsole.push(InteractiveConsole.java:84)
	at org.python.util.InteractiveConsole.interact(InteractiveConsole.java:63)
	at org.python.util.jpython.main(jpython.java:141)

java.lang.IllegalAccessException: java.lang.IllegalAccessException:
testpackage/Bar
msg141 (view) Author: Finn Bock (bckfnn) Date: 2000-11-23.09:06:39
I don't think this is solvable at all! The method is accessible through java but inaccessible through reflection!
msg142 (view) Author: ian west (ianzsk) Date: 2001-02-16.07:05:02
this is a similar bug to #132462
I've altered a few methods in PyJavaClass and added another Options flag
to use the JavaAccessibility.setAccessible()  to "mimic" the equivalent
Java access. (Now if I can only give jython classes access to protected members
of Java super classes!)
msg143 (view) Author: Attila Szegedi (szegedia) Date: 2002-10-10.11:37:14
Logged In: YES 
user_id=52489

This exception is completely in place. Think about it: you 
can't call this method statically from Java as well - 
  ((Bar)object).hi()
is illegal as the compiler won't let you even cast an object 
reference to Bar. When you call a method by name, and the 
method is in a non-public class, you have to lookup the same 
method in the public superclasses and superinterfaces of the 
class. This is how you "upcast" to public class/interface in 
the reflection world. If there's no public superclass/interface 
with this method, you just *can't call* the method. This was 
encountered in other scriptlike environments as well -- I did 
this "dynamic upcast" logic for both FreeMarker and Velocity 
template engines in the past.
msg144 (view) Author: Bill Smith (satayboy) Date: 2002-12-05.05:05:11
Logged In: YES 
user_id=424186

I don't understand the previous post.  You can call that 
method using a normal Java method call.  Isn't the problem 
with how Jython uses Java reflection?  As ianzsk pointed out, 
Jython could use the setAccessible method to make the 
method callable.  Or Jython could add delegator methods to 
the wrapper class.

This bug is preventing me from using the httpunit package.  
I'm having a hard time figuring out how to work around it in 
Jython 2.1.  Changing my jython script to lookup the method 
object and set its accessibility doesn't seem to do the trick.
msg145 (view) Author: Kyun Sang Song (jeffsong) Date: 2003-02-21.04:54:32
Logged In: YES 
user_id=638940


package anotherpackage;

import java.lang.reflect.*;

public class Test {
  
  public static void main(String[] args) throws Exception {
    
    //(new testpackage.Foo()).hi();
    
    Class c = Class.forName("testpackage.Foo");
    Object instance = c.newInstance();
    
    Method hi = c.getMethod("hi",null);
    
    hi.invoke(instance,null);
    
  }
  
}


This is a bug?  So then Java's Bug...
msg146 (view) Author: Martin Fuzzey (mfuzzey) Date: 2003-11-25.15:53:30
Logged In: YES 
user_id=698912

I have a variant on this problem.
public interface Itf {
    public myMethod();
}

abstract class BaseClass {  <-- Package protected
    public myMethod() { ... }
}

class Impl extends BaseClass implements Itf { <-- Package
protected
}

If I now obtain an instance of Impl and try to call myMethod
on it from Jython I get an illegal access error even though
this class implements an interface defining the method.

In Java I can do it by casting to Itf.

Not that if I make BaseClass implement Itf all works fine...

Also I can't find bug #132462 mentionned below...

Martin
msg147 (view) Author: Ype (ype) Date: 2004-05-03.21:27:37
Logged In: YES 
user_id=125722

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.  
 
msg148 (view) Author: Charlie Groves (cgroves) Date: 2006-08-18.02:30:16
Logged In: YES 
user_id=1174327

Tested by test232, fixed in r2889.
History
Date User Action Args
2000-11-18 19:31:07bckfnncreate