Re: problem with class accessiblity check in invoke (natMethod.cc)

Erik Groeneveld <[email protected]>
Newsgroups gmane.comp.gcc.java.devel
Message-ID <[email protected]>
On Wed, Dec 23, 2009 at 17:44, Bryce McKinlay <[email protected]> wrote:
> On Wed, Dec 23, 2009 at 3:58 PM, Erik J Groeneveld <[email protected]> wrote:
[...]

> In your example, you aren't testing the accessibility of Iterator, but
> rather that of the class which is returned by ArrayList.iterator(),
> which is indeed a package-private class from a different package!

That is true. But the code that uses invoke is generic.  It calls a
given method on a given object:

java::lang::Object* callMethod(java::lang::Object* target,
java::lang::String* methodname)

It cannot do anything else than trying to find the method using the
java::lang::Object pointer that has been passed to it.  And it cannot
tell from this pointer that the actual reference the application is
using is of type Iterator (or any other interface for that matter).
This is something the compiler can work out, but not the runtime.
Indeed this works:

    java::util::ArrayList* l = new java::util::ArrayList();
    java::util::Iterator* i = l->iterator();
    i = l->iterator();
    i->hasNext();

But the fix below only works for the example I made up because a human
can tell the reference is of type Iterator:

> Another fix for your code would be to change:
>
>   java::lang::reflect::Method* m = i->getClass()->getDeclaredMethod(
>           JvNewStringUTF("hasNext"), NULL);
>
> to something like:
>
>   java::lang::reflect::Method* m =
> &(java::util::Iterator::class$)->getDeclaredMethod(
>              JvNewStringUTF("hasNext"), NULL);

So I wonder how the rules from 6.6 in the Java Language Specification
can be implemented properly when the type of the reference is not
known to invoke.  Because the relevant part of the spec speaks about
"members of a reference".

"A member (class, interface, field, or method) of a reference (class,
interface, or array) type or a constructor of a class type is
accessible only if the type is accessible and the member or
constructor is declared to permit access: ..."

but invoke simply does not know the reference, and cannot get it from
the Java call stack either (hence the core dump).  All it knows is the
actual object, and this object is of a type that is not accessible,
although it implements an interface that is accessible.

Is there a more gentle solution other than calling setAccessible() on
the method object? (which works)  Could it be done in GCJ?

Erik
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.