Hi Tim

Looks fine to me too...

/Jeppe

> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:stripes-
> [EMAIL PROTECTED] On Behalf Of Tim Fennell
> Sent: 2. april 2007 16:14
> To: Stripes Development List
> Subject: [Stripes-dev] Introspector/PropertyDescriptor issues
> 
> Hey All,
> 
> I've been working on a bug fix for STS-330, which describes a bug
> whereby the property binding code doesn't like working with
> Map.Entry's (and more generally, public properties specified in
> public interfaces, and implemented in private classes).
> 
> I've tracked down what I believe is the cause of the problem, and
> have a nice little test case and solution - but since this looks to
> me like a bug in Sun's Java implementation, I'd really like to get
> some other opinions on it before I a) work around it and b) post it
> to the bug parade.
> 
> Essentially what's happening is as follows.  When introspecting a
> class which is private, but is an implementation of a public
> interface, the Introspector returns PropertyDescriptors which contain
> references to the methods in the private class instead of those in
> the public interface. The JLS (section 6.6.1) defines an object as
> accessible (assuming it's in a different package) only if the object
> is public and the type containing it is public - which in this case
> it's not.  So when you invoke the read or write methods, you get
> access exceptions :(  This seems to be a bug in the Introspector if
> you ask me.
> 
> The second bizarro thing I discovered is that calling isAccessible()
> on public methods of public interfaces seems to return false!  So
> you'll see in the example code below that I actually check the
> interface and member for the public modifier, because isAccessible()
> returns false.  I can't find anything either way on this in the JLS,
> but given the prior statement (if the member is public and the type
> is public) and no contrary statements about requiring concrete types,
> this seems like a bug also!
> 
> Anyway, if someone could take a few minutes to read through the test
> case below, and see if you can find some holes in my logic, I'd
> appreciate it.
> 
> -t
> 
> -------------------------------------------------------
> 
> package net.sourceforge.stripes.test;
> 
> import java.beans.BeanInfo;
> import java.beans.Introspector;
> import java.beans.PropertyDescriptor;
> import java.lang.reflect.Method;
> import static java.lang.reflect.Modifier.isPublic;
> import java.util.HashMap;
> import java.util.Map;
> 
> public class PrivateInnerTest {
>      public static void main(String[] args) throws Exception {
>          Map<String,String> map = new HashMap<String,String>();
>          map.put("foo", "bar");
>          Map.Entry<String,String> entry = map.entrySet().iterator
> ().next();
> 
>          BeanInfo info = Introspector.getBeanInfo(entry.getClass());
>          for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
>              Method m1 = pd.getReadMethod();
>              Method m2 = resolveAccessibleMethod(m1);
> 
>              //Works
>              System.out.println(pd.getName() + ": " + m2.invoke(entry));
> 
>              // Explodes sometimes
>              System.out.println(pd.getName() + ": " + m1.invoke(entry));
>          }
>      }
> 
>      public static final Method resolveAccessibleMethod(Method m)
> throws Exception {
>          // If the passed in method is accessible, then just give it
> back.
>          if (m.isAccessible()) return m;
> 
>          final Class<?> clazz    = m.getDeclaringClass();
>          final String name    = m.getName();
>          final Class<?>[] ptypes = m.getParameterTypes();
> 
>          // Else, loop through the interfaces for the declaring
> class, looking for a
>          // public version of the method that we can call
>          for (Class<?> iface : clazz.getInterfaces()) {
>              try {
>                  Method m2 = iface.getMethod(name, ptypes);
>                  if (m2.isAccessible()) return m2;
>                  if (isPublic(iface.getModifiers()) && isPublic
> (m2.getModifiers())) return m2;
>              }
>              catch (NoSuchMethodException nsme) { /* Not Unexpected.
> */ }
>          }
> 
>          // Else loop through the superclasses looking for a public
> method
>          Class<?> c = clazz.getSuperclass();
>          while (c != null) {
>              try {
>                  Method m2 = c.getMethod(name, ptypes);
>                  if (m2.isAccessible()) return m2;
>                  if (isPublic(c.getModifiers()) && isPublic
> (m2.getModifiers())) return m2;
>              }
>              catch (NoSuchMethodException nsme) { /* Not Unexpected.
> */ }
> 
>              c = c.getSuperclass();
>          }
> 
>          // If we haven't found anything at this point, just give up!
>          return m;
>      }
> }
> 
> 
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share
> your
> opinions on IT & business topics through brief surveys-and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Stripes-development mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/stripes-development
> 
> 
> __________ NOD32 2164 (20070402) Information __________
> 
> This message was checked by NOD32 antivirus system.
> http://www.eset.com



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to