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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 >>>>> >>>>> >>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> >> >
