click-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bob Schellink <sab...@gmail.com>
Subject Re: "Wrong Number of Arguments" Error in Form.copyTo()
Date Mon, 20 Oct 2008 16:40:56 GMT
Hi Alvin,

I've checked in some code today which might resolve your issue.

If you have multiple overloaded getters (e.g. getters with same name 
but different args) in your class, it seems that Click might pick the 
wrong getter which accepts arguments. This could lead to the error you 
experience.

You can test this by replacing your copy of 
net.sf.click.util.ContainerUtils with this one:
http://click.svn.sourceforge.net/viewvc/click/trunk/click/framework/src/net/sf/click/util/ContainerUtils.java?revision=3540

Let us know if that resolves the issue.

Thanks.

bob

Bob Schellink wrote:
> Hmm nasty. Are you using JDK 1.4 or 1.5?
> 
> Perhaps you have a getter which accepts an argument? That would 
> certainly throw IllegalArgumentException too.
> 
> Anyway I think we need to improve the exception handling a bit to 
> provide more information for debugging.
> 
> Below is my proposed change to ContainerUtils#ensureObjectPathNotNull.
> 
> If you can replace the method with the one below it should provide 
> better info on which method with what parameter
> is giving problems.
> 
> Let me know if this shed some light on the issue.
> 
> 
> private static void ensureObjectPathNotNull(Object object, String path) {
> 
>        final int index = path.indexOf('.');
> 
>        if (index == -1) {
>            return;
>        }
> 
>        String value = path.substring(0, index);
>        String getterName = ClickUtils.toGetterName(value);
>        String isGetterName = ClickUtils.toIsGetterName(value);
> 
>        Method foundMethod = null;
>        Method[] methods = object.getClass().getMethods();
>        for (int i = 0; i < methods.length; i++) {
>            String name = methods[i].getName();
>            if (name.equals(getterName)) {
>                foundMethod = methods[i];
>                break;
> 
>            } else if (name.equals(isGetterName)) {
>                foundMethod = methods[i];
>                break;
>            }
>        }
> 
>        if (foundMethod == null) {
>            String msg =
>                "Getter method not found on class : " + object.getClass()
>                + " for path value : " + value;
>            throw new RuntimeException(msg);
>        }
> 
>        try {
>            Object result = foundMethod.invoke(object, new Object[0]);
> 
>            if (result == null) {
>                result = foundMethod.getReturnType().newInstance();
> 
>                String setterName = ClickUtils.toSetterName(value);
>                Class[] classArgs = { foundMethod.getReturnType() };
> 
>                Method setterMethod =
>                    object.getClass().getMethod(setterName, classArgs);
> 
>                Object[] objectArgs = { result };
> 
>                setterMethod.invoke(object, objectArgs);
>            }
> 
>            String remainingPath = path.substring(index + 1);
> 
>            ensureObjectPathNotNull(result, remainingPath);
> 
>        } catch (Exception e) {
>            HtmlStringBuffer buffer = new HtmlStringBuffer();
>            Class[] parameterTypes = foundMethod.getParameterTypes();
>            buffer.append("(");
>            if (parameterTypes != null) {
>                for (int i = 0; i < parameterTypes.length; i++) {
>                    buffer.append(parameterTypes[i].getName());
>                    if (i < parameterTypes.length - 1) {
>                        buffer.append(", ");
>                    }
>                }
>            }
>            buffer.append(")");
>            String msg = "Error occurred while ensuring path is not null 
> for"
>                + " class : " + object.getClass() + ", method : "
>                + foundMethod.getName() + buffer.toString() + " and 
> return type : "
>                + foundMethod.getReturnType();
>            throw new RuntimeException(msg, e);
>        }
>    }
> 
> 
> 
> 
> Alvin Townsend wrote:
>> Hi Bob,
>>
>> That largely is the behavior I observe everywhere else in the
>> application. For reasons unknown, just in this one place, we get this
>> error. (Even odder is that I cannot replicate the error in my IDE,
>> (Ganymede) only when packaged and deployed to Tomcat.)
>>
>> Thank you much for the help!
>>
>> Alvin
>>
>> On Sun, Oct 19, 2008 at 3:42 PM, Bob Schellink <sabob1@gmail.com> wrote:
>>  
>>> Alvin Townsend wrote:
>>>    
>>>> Hi Bob,
>>>>
>>>> That makes a lot of sense. Many of our objects cannot be instantiated
>>>> without arguments to the Constructors, so I've made sure that all of
>>>> them were set up previously and that the Form.copyTo wouldn't come
>>>> across anything null.
>>>>
>>>>       
>>> Here is some more info. Click calls the getter method of the path to 
>>> figure
>>> out whether to instantiate
>>> a new instance or not.
>>>
>>> field = new TextField("address.street");
>>> form.copyTo(client);
>>>
>>> From the above Click will tokenize the field path into "address" and
>>> "street". Next it will try and check if
>>> address is null through reflection by invoking the address getter:
>>>
>>> client.getAddress();
>>>
>>> If client.getAddress returns null Click tries and instantiates the 
>>> Address.
>>>
>>> If you use a debugger you can place a breakpoint roughly on line 595 of
>>> class net.sf.click.util.ContainerUtils#ensureObjectPathNotNull.
>>> If your breakpoint is hit, it means Click tries to instantiate a 
>>> object...
>>>
>>> kind regards
>>>
>>> bob
>>>
>>>
>>>
>>>
>>>     
>>
>>   
> 
> 


Mime
View raw message