This is another workaround for the problem I raised a few days ago see the
thread:
http://www.mail-archive.com/velocity-dev%40jakarta.apache.org/msg03686.html
I think that the best solution is not to do that but to keep track of the
type of the object you are manipulating rather than deal with Object and get
its class via getClass().
It is not natural otherwise. We invoked the method so we are perfectly able
to know the return type of the method we invoked rather than to work w/ the
instance object, because in fact what we are doing here is upcasting.
--
Stéphane Bailliez
Software Engineer, Paris - France
iMediation - http://www.imediation.com
Disclaimer: All the opinions expressed above are mine and not those from my
company.
> -----Original Message-----
> From: Szegedi Attila [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, August 02, 2001 4:09 PM
> To: [EMAIL PROTECTED]
> Subject: [PATCH] dynamic casting to avoid IllegalAccessExceptions
>
>
> Right now it's easy to run into IllegalAccessException with Velocity
> although the called method is (or at least, seems to be)
> public since it has
> no dynamic casting.
>
> Consider for example enumerating entries of a HashMap:
>
> #foreach ($entry in $hashmap.entrySet())
> $entry.key = $entry.value
> #end
>
> While this seems innocent, it in fact does not work - it dies with an
> IllegalAccessException. Why, you might ask?
> Each entry of a HashMap is an instance of HashMap.Entry, which is a
> *private* class in HashMap. When you try to call the getKey()
> method on an
> entry, you're doing the dynamic equivalent of the following
> Java expression:
>
> ((HashMap.Entry)entry).getKey()
>
> which clearly wouldn't even compile, let alone run as you are
> not allowed to
> cast an object into HashMap's private inner class.
> What you would like to do were this static code is probably
>
> ((Map.Entry)entry).getKey()
>
> as Map.Entry is a public interface, therefore legal to cast
> to and use.
>
> However, for this you need the Method object returned from
> Map.Entry.class.getMethod("getKey", null) instead of the one
> returned from
> HashMap.Entry.class.getMethod("getKey", null).
>
> Therefore, before a public(ly looking) method can be used, it must be
> checked whether it's declaring class is itself public. If it
> isn't, you must
> first find a legal "cast" dinamically, that is do a lookup
> for a public
> method with same signature in the declaring class' public
> superclasses and
> implemented interfaces. If you find one -- that's the right
> one to use. If
> you don't find any -- it's legal, altough quite a semantic
> nonsense you
> shouldn't encounter in a well designed class (namely, it's a
> public method
> of a non-public class that isn't publicly declared in any
> public superclass
> or interface -- so it does not make sense for it to be public
> at all, since
> it's not accessible outside the package).
>
> I've added a "Method getPublicMethod(Method)" method (try reading this
> sentence aloud :-)) to
> org.apache.velocity.util.introspection.Introspector
> that does the job. Also made ClassMap, ASTReference, and
> PropertyExecutor
> use it. The diff -u patches are attached.
>
> BTW, is there any particular reason you folks aren't using
> java.beans.Introspector under covers of Velocity's own Introspector?
>
> Cheers,
> Attila.
>
>