mercredi 18 mai 2016

NosuchMethod exception is thrown when trying to access a method using javaassist

I'm getting a NoSuchMethodException when trying to set value for a method that accepts a reference (instance of a class).I'm using Javaassist.

Codelass that creates & return classes in run time.

  public class DynamicPojoGeneration {
  static ClassPool pool = ClassPool.getDefault();   
  public static Class generate(String className, Map<String, Class<?>>  properties) throws NotFoundException,   CannotCompileException,ClassNotFoundException {
    Loader L1 = new Loader(pool);
    CtClass cc; 
    System.out.println("Checking whether class " +className+ " is present in classloader ");
    System.out.println(CheckClass(className));
    if (!CheckClass(className) == true) {   
        cc = pool.makeClass(className);
        cc.addInterface(getCtClass(Serializable.class));
        CtField field;
        // Iterating the map to create getter and setter methods
        for (String str : properties.keySet()) {
            field = new CtField(getCtClass(properties.get(str)), str, cc);
            cc.addField(field);             
            cc.addMethod(CtNewMethod.getter("get" + str, field));
            cc.addMethod(CtNewMethod.setter("set" + str, field));
        }
        return cc.toClass();
    }
    else {
        Class<?> cl = L1.loadClass(className);          
        return cl;                      
    }               
}

}

My test code:

   public class CheckPojoGeneration {
   public static void main(String[] args) {
    HashMap<String, Class<?>> props = new HashMap<String, Class<?>>();
    HashMap<String, Object> valueMap = new HashMap<String, Object>();
    HashMap<String, Class<?>> phoneProps = new HashMap<String, Class<?>>();
    HashMap<String, String> phoneValueMap = new HashMap<String, String>();
    phoneProps.put("phoneNumber", String.class);
    phoneValueMap.put("phoneNumber", "Ambrose");
    props.put("fName", String.class);
    valueMap.put("fName", "101");           
    try {
        Class phoneClass = DynamicPojoGeneration.generate("Phone", phoneProps);
        Object phoneObject = phoneClass.newInstance();
        // Adding phone as a member variable to Address class 
        props.put("phone", phoneObject.getClass());
        valueMap.put("phone", phoneObject);
        Class dummyClass = DynamicPojoGeneration.generate("Address", props);
        Object obj = dummyClass.newInstance();  
        Method m;
        // Setting values for attributes using setters
        for (String str : valueMap.keySet()) {              
            m = dummyClass.getMethod("set" + str, props.get(str));                      
            m.invoke(obj, valueMap.get(str));
        }           
        // Accessing the same class - This time classes should be loaded from class pool instead of created.            
        Class phoneClass2 = DynamicPojoGeneration.generate("Phone", phoneProps);
        Object phoneObject2 = phoneClass2.newInstance();
        HashMap<String, Class<?>> props2 = new HashMap<String, Class<?>>();
        HashMap<String, Object> valueMap2 = new HashMap<String, Object>();
        props2.put("fName", String.class);
        valueMap2.put("fName", "test");     
        props2.put("phone",phoneObject2.getClass());
        valueMap2.put("phonehone", phoneObject2);
        Class dummyClass2 = DynamicPojoGeneration.generate("Address", props2);
        Object obj2 = dummyClass2.newInstance();
        Method m2;  
        // Setting values for attributes using setters
        for (String str : valueMap2.keySet()) {             
            m2 = dummyClass2.getMethod("set" + str, props2.get(str));   // Exception is thrown here         
            m2.invoke(obj2, valueMap2.get(str));                    
        }           
    } // Exception handling
}

}

I get NoSuchMethodException thrown - Account.setPhoneType(Phone). This happens only in the second instance. In the first instance, i'm able to set the phone & access it.





Aucun commentaire:

Enregistrer un commentaire