commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Arun Thomas" <arun.tho...@paybytouch.com>
Subject RE: [BEANUTILS] Property Descriptor Visibility
Date Tue, 14 Oct 2003 18:56:21 GMT
Henning, 

While this might seem like a problem with the MethodUtils::getAccessibleMethod, it, in fact,
reflects the reality of dynamic method invocation today (the behaviour is broken because these
methods can be invoked directly, just not dynamically).  When I first encountered this problem,
I was completely perplexed, but it turns out to be just the way the JRE's are written.  FYI,
I've cut and pasted classes for a simple example below which does not use MethodUtils, but
simply tries to dynamically invoke a method that belongs to a base class.  Here's the output
when the base class is package protected:

  Vendor Version: Sun Microsystems Inc. 1.4.1_02
  Property Name: mail
  Getter Method: public java.lang.String pkg.Base.getMail()
  Results of Invocation: IllegalAccessException

If I make the Base class public:

  Vendor Version: Sun Microsystems Inc. 1.4.1_02
  Property Name: mail
  Getter Method: public java.lang.String pkg.Base.getMail()
  Results of Invocation: You've Got Mail!

The problem also holds true for the IBM JRE (which is what I normally use):

  Vendor Version: IBM Corporation 1.3.1
  Property Name: mail
  Getter Method: public java.lang.String pkg.Base.getMail()
  Results of Invocation: IllegalAccessException

I would say, therefore, that changing this behaviour in MethodUtils is not particularly useful
because PropertyUtils would then fail at actually invoking the method.  The only solution
today seems to be to make the base class accessible.  If you find another, I'd be keen to
know what it is.  

-AMT

-----------------------------------------------------------------------
package pkg;

class Base {
    public String getMail() {
        return "You've Got Mail!";
    }
}

-----------------------------------------------------------------------package pkg;

public class SubBase extends Base {}

-----------------------------------------------------------------------package subpkg;

import pkg.SubBase;

public class Test {
    public static void main(String[] args) throws Exception {
        System.out.println(
            "Vendor Version: "
                + System.getProperty("java.vendor")
                + " "
                + System.getProperty("java.version"));

        java.beans.PropertyDescriptor[] desc =
            java
                .beans
                .Introspector
                .getBeanInfo(SubBase.class)
                .getPropertyDescriptors();

        int i = desc.length;
        while (--i >= 0) {
            if (desc[i].getName().equals("mail")) {
                System.out.println("Property Name: " + desc[i].getName());
                System.out.println("Getter Method: " + desc[i].getReadMethod());

                System.out.print("Results of Invocation: ");
                try { 
                    System.out.println(
                        desc[i].getReadMethod().invoke(
                            new SubBase(),
                            new Object[0]));
                } catch (IllegalAccessException e) {
                    System.out.println("IllegalAccessException");
                }
            }
        }
    }
}
-----Original Message-----
From: Henning Schmiedehausen [mailto:hps@intermeta.de] 
Sent: Tuesday, October 14, 2003 1:49 AM
To: commons-dev@jakarta.apache.org
Subject: [BEANUTILS] Property Descriptor Visibility


Hi,

consider the following beans:

--- cut ---
package beans;

abstract class AbstractBean {
  private String foo = null;

  public AbstractBean() {}

  public String getFoo() { return this.foo; };

  public void setFoo(String foo) { this.foo = foo; };
}
--- cut ---

--- cut ---
package beans;

public class PublicBean
  extends AbstractBean {
  private String bar = null;

  public PublicBeanBean() { super(); }

  public String getBar() { return this.bar; };

  public void setBar(String bar) { this.bar = bar; };
}
--- cut ---

import beans.PublicBean;
[...]
PublicBean bean = new PublicBean(); BeanUtils.setSimpleProperty(bean,  "foo", "value");

fails. The reason for this is the Property visibility check in the MethodUtils::getAccessibleMethod,
which considers the "setFoo/getFoo" Property setters to be inaccessible because they're not
defined in a public class and not defined by any Interface implemented by the Bean.

My question now is: Is this correct? The public visibility of the PublicBean class makes IMHO
the public methods AbstractBean::setFoo() and AbstractBean::getFoo() accessible, even if the
declaring class
(AbstractBean) is not public.

This is not an academic question, it is exactly the problem I've written about yesterday with
commons-dbcp. There is "public SharedPoolDataSource" which extends "abstract InstanceKeyDataSource".
One cannot set properties defined in InstanceKeyDataSource with PropertyUtils because of this
problem.

I'd be interested if the correct solution is to add a "public" to InstanceKeyDataSource or
rewrite the 
MethodUtils::getAccessibleMethod().

        Regards
                Henning


-- 
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen          INTERMETA GmbH
hps@intermeta.de        +49 9131 50 654 0   http://www.intermeta.de/

Java, perl, Solaris, Linux, xSP Consulting, Web Services 
freelance consultant -- Jakarta Turbine Development  -- hero for hire

"Dominate!! Dominate!! Eat your young and aggregate! I have grotty silicon!" 
      -- AOL CD when played backwards  (User Friendly - 200-10-15)


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message