click-user mailing list archives

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

Your change fixed the problem. The form values were copied to the
object correctly, nothing went BOOM, and all proceeded as expected.

I am assuming that the fix is *not* in RC3? If not, are you planning
on an RC4 or should I get the source for RC3, add the patch, and go
with that?

Thank you!

Alvin

On Mon, Oct 20, 2008 at 1:40 PM, Alvin Townsend
<alvin.townsend@gmail.com> wrote:
> Bob,
>
> I will download and test and let you know the results.
>
> Thank you much.
>
> Alvin
>
> On Mon, Oct 20, 2008 at 12:40 PM, Bob Schellink <sabob1@gmail.com> wrote:
>> 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