0

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

2 Answers 2

2

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 .

Sign up to request clarification or add additional context in comments.

Comments

0

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();
        }
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.