4

Hi I am receiving the above error when I run my code. I am having trouble understanding what is causing the error. I have seen the solution on a similar thread but I am not sure if this applies in my case. Can someone please help me make some sense of this? Any help is greatly appreciated.

ERROR

[org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/window].[jsp]]
Servlet.service() for servlet jsp threw exception
java.lang.IllegalArgumentException: object is not an instance of
declaring class     at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)     at
com.container.taglib.util.MirrorMaker.invokeMethod(MirrorMaker.java:54)
    at
com.container.taglib.util.MirrorMaker.invokeMethod(MirrorMaker.java:48)
    at
com.container.taglib.list.TableSorter.invokeMethod(TableSorter.java:1092)
    at
com.container.taglib.list.TableSorter.createList(TableSorter.java:503)
    at
com.container.taglib.list.TableSorter.doAfterBody(TableSorter.java:151)

Code:

public static Object invokeMethod(Object obj, Method method, Object[] params)throws IllegalAccessException, InvocationTargetException{
    Object ret = null;
    String str = "";
    try{
        ret = method.invoke(obj, params);
        if(ret instanceof String){
            str = (String)ret;
            //logger.info("ret str: "+str);                        
        }else if(ret instanceof Integer){
            str = ((Integer)ret).toString();
            //logger.info("ret int: "+str);
        }else if(ret instanceof java.util.Date){
            str = new SimpleDateFormat("yyyy-MM-dd").format(ret);
            logger.info("ret date: "+str);
        }else if(ret instanceof Double) {
            str = ((Double)ret).toString();
        }else if(ret instanceof ArrayList){
            return ret;
        }else{
            return ret;
        }

    }catch(IllegalAccessException ex){
        logger.info("illegal access");
        throw ex;
    }catch(InvocationTargetException ex){
        logger.error("invocation target ex");
        throw ex;
    }           
    return str;
}
Community
  • 1
  • 1
billy_blanks
  • 105
  • 1
  • 3
  • 12
  • It looks like your object that you are passing as the obj parameter is not able to invoke the method. Try using method.invoke((Object) null, (Object) null); to debug. Comment back on what happens. – DankMemes Aug 16 '12 at 17:27
  • You say that you are not sure that the answer you link to applies in your case. Can you say why you think it might not apply? – Luke Woodward Aug 16 '12 at 21:28

1 Answers1

4

There is no reason for this exception being thrown other than by trying to use the reflection API to invoke a method using an object that is not an instance of the class that declares the method.

The error message you get back from the reflection API doesn't help you a great deal figuring out exactly what went wrong. Adding a check such as the following to your invokeMethod function could provide more useful information:

if (!Modifier.isStatic(method.getModifiers())) {
    if (obj == null) {
        throw new NullPointerException("obj is null");
    } else if (!method.getDeclaringClass().isAssignableFrom(obj.getClass())) {
        throw new IllegalArgumentException(
            "Cannot call method '" + method + "' of class '" + method.getDeclaringClass().getName()
            + "' using object '" + obj + "' of class '" + obj.getClass().getName() + "' because"
            + " object '" + obj + "' is not an instance of '" + method.getDeclaringClass().getName() + "'");
    }
}

This code will check for an object being an instance of the class that declares the method, and if not, throw an exception with more details about the object and the method's declaring class.

It seems your code is part of a web application. I can speculate that the class of obj and the declaring class of Method might be two different copies of the same class loaded in two separate classloaders. (In Tomcat, each web application uses its own classloader.) However, without being able to see your code and how you are running it, this is nothing more than a complete stab in the dark.

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • Thank you Luke. I am now getting the following:Cannot call method 'public java.lang.String com.psc.site.form.ReportForm.getPayId()'of class 'com.psc.site.form.ReportForm'using object '[com.psc.site.form.ReportForm@14f54ea]' of class 'java.util.ArrayList' because object '[com.psc.site.form.ReportForm@14f54ea]' is not an instance of 'com.psc.site.form.ReportForm' – billy_blanks Aug 22 '12 at 17:14
  • 1
    The message you've posted says that `obj` is an `ArrayList`, not a `ReportForm`. You can't call `ReportForm` methods on an `ArrayList`, and that's why you get the exception. I can also see from the message that the list contains one item. You'll need to fetch this one item out of the `ArrayList` and pass it to your `invokeMethod` method, instead of passing the list to `invokeMethod`. – Luke Woodward Aug 23 '12 at 21:39