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