Unable to reflect. Exception java.lang.IllegalArgumentException: object is not an instance of declaring class

I have two different classes one is with validating method bellow.

@Validator
public boolean validIdentifier() throws IllegalArgumentException, IllegalAccessException{
        boolean flag=false;
        Field[] fields=this.data.getClass().getDeclaredFields();
        for(Field field : fields) {
            if (!field.isAccessible()){
                field.setAccessible(true);
            }       
            if (field.getName().endsWith("Identifier") && field.get(data)!=null){
                flag=true;
                field.setAccessible(false);
                break;
            }
            field.setAccessible(false);
        }
        return flag;
}

The other one has two methods that reflect on the above validating method like this

public void validate(){
  AppValidator validator=new AppValidator(somebean);
  doCommonValidation(validator.getClass());
}

public void doCommonValidation(Class clazz){
        Method[] methods = clazz.getMethods();
        for(Method method:methods) {
            for(Annotation annotation:method.getAnnotations()){
                try {
                    if (annotation instanceof Validator && !(boolean)method.invoke(clazz)){ //exception is here
                        String errorMessage = ((Validator)annotation).message();
                        String display=((Validator)annotation).displayField();
                        if(errorMessage != null) {
                            System.out.println(display+":"+errorMessage);
                        }
                    }
                } catch (IllegalAccessException | IllegalArgumentException
                        | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

}

The above code throws java.lang.IllegalArgumentException: object is not an instance of declaring class.

If I change doCommonValidation and by-pass validate method like this, everything works.

public void validate() {
        try {
            AppValidator validator=new AppValidator(someBean);
            Method[] methods = validator.getClass().getMethods();           
            for(Method method:methods) {
                for(Annotation annotation:method.getAnnotations()){
                    if (annotation instanceof ValidatingMethod && !(boolean)method.invoke(validator)){
                        String errorMessage = ((ValidatingMethod)annotation).message();
                        String display=((ValidatingMethod)annotation).displayField();
                        if(errorMessage != null) {
                            System.out.println(display+":"+errorMessage);
                        }
                    }
                }
            }

        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) {
            e.printStackTrace();
            return new HashMap<String, String>();
        }
}

The issue is that I do need to be able to plugin several different validating classes. If I explicilty instanciate them then I have to write repeating code where the only diffirence is the class that I reflect on.

I don't understand why in the first case I get the exception and in the second I don't. Any ideas?

Thank you

Answers


When you execute this line in the erroneous case:

if (annotation instanceof Validator && !(boolean)method.invoke(clazz))

you need to pass to the invoke method a parameter representing the object on which to invoke the method, as it is an instance method. This parameter should be of type denoted by the Class instance passed as parameter to the doCommonValidation(Class) method. What you pass is an instance of Class<T>, rather than an instance of .


I figured it out. The worst thing was that the answer was in front of me all the time!

I need to invoke method on the object not the class. Hence validate method should look like this.

public void validate(){
  AppValidator validator=new AppValidator(somebean);
  doCommonValidation(validator);
}

and doCommonValidation method should look like this

public void doCommonValidation(Object obj){
    Method[] methods = obj.getClass().getMethods();
    for(Method method:methods) {
        for(Annotation annotation:method.getAnnotations()){
        try {
            if (annotation instanceof Validator && !(boolean)method.invoke(obj)){ 
            String errorMessage = ((Validator)annotation).message();
            String display=((Validator)annotation).displayField();
            if(errorMessage != null) {
                System.out.println(display+":"+errorMessage);
            }
            }
        } catch (IllegalAccessException | IllegalArgumentException
            | InvocationTargetException e) {
            e.printStackTrace();
        }
        }
    }
}

Need Your Help

Moving a window between workspaces/virtual desktops

wxpython x11 window-managers

I have a Linux-only wxPython application with a wxFrame that acts as a menu/toolbar, it can open up new windows that are independent of the toolbar itself. Since the user can move any of these win...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.