简体   繁体   中英

java assist creating dynamic class and its object

i am trying to create a dynamic class and its object and trying to call method of method of class dynamic using object but i am getting following error

java.lang.ClassNotFoundException: Eval

here is my code please suggest any changes to make it run successfully

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtNewMethod;
public class DyanamicClass {
/**
 * @param args
 */
public static void main (String[] args) throws Exception {

    createClass();
    Object obj=createObject();
    Object[] actualParams = new Object[] { new Double(17) };
    callMethod("eval", obj,actualParams);
}

public static void  createClass()
{
    ClassPool pool = ClassPool.getDefault();

    CtClass evalClass = pool.makeClass("Eval");

    try {
        evalClass.addMethod(
            CtNewMethod.make("public double eval (double x) { return x ; }", evalClass));

    } catch (CannotCompileException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public static Object createObject()
{
    Object obj=null;
    try {
        Class clazz = Class.forName("Eval");
        obj=clazz.newInstance();

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return obj;
}

public static void callMethod(String name,Object obj,Object [] actualParams)
{
    Class[] formalParams = new Class[] { double.class };
    double result;
    try {
        Class clazz=Class.forName("Eval");

        Method meth = clazz.getDeclaredMethod(name, formalParams);

        result = ((Double) meth.invoke(obj, actualParams)).doubleValue();
        System.out.println(result);
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

}

I have tested some things in the implementation of the Javassist. Understand that i dont understand this library, but my assumption is that the ClassLoader used by the Class.forName() (Probably the current Thread context class loader - need to check that) cannot find the class file for Eval because it is does not have information on its classpath. I am very sure the javassist has ClassPath information you need to set for the class in order for the normal ClassLoaders be able to find its class file information. Moreover, you probably need to save the class file to file provided by the javassist.

However, as a work around, do the following (Note, that javassist says that after calling toClass() on CtClass, it cannot be used again).

CtClass ct =ClassPool.getDefault().getCtClass("Eval");
System.out.println(ct);
Class cl = ct.toClass();
Object o  = cl.newInstance();
Method m = cl.getDeclaredMethod("eval", new Class[]{double.class});
Object res = m.invoke(o, 56);
System.out.println(res);
System.out.println(cl);
System.out.println(Arrays.toString(cl.getDeclaredMethods()));

You are trying to load your class here:

Class clazz = Class.forName("Eval");
  1. Make sure class Eval is available in your classpath.
  2. Instead of class name Eval you have to give packageName.className so something like org.test.Eval .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM