0

動的クラスとそのオブジェクトを作成しようとしており、オブジェクトを使用して動的クラスのメソッドのメソッドを呼び出そうとしていますが、次のエラーが発生しています

java.lang.ClassNotFoundException: Eval

これが私のコードです 正常に実行するための変更を提案してください

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


}

}

4

2 に答える 2

1

Javassist の実装でいくつかのことをテストしました。私はこのライブラリを理解していないことを理解していますが、Class.forName() で使用される ClassLoader (おそらく現在の Thread コンテキスト クラス ローダー - それを確認する必要があります) が Eval のクラス ファイルを見つけられないということを前提としています。そのクラスパスに関する情報。javassist には、通常の ClassLoaders がそのクラス ファイル情報を見つけることができるようにするために、クラスに設定する必要がある ClassPath 情報があると確信しています。さらに、javassist が提供するファイルにクラス ファイルを保存する必要がある場合があります。

ただし、回避策として、次のことを行ってください (javassist は、CtClass で toClass() を呼び出した後は、再度使用できないと言っています)。

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()));
于 2012-05-11T10:40:17.483 に答える
0

ここにクラスをロードしようとしています:

Class clazz = Class.forName("Eval");
  1. Evalクラスがクラスパスで利用可能であることを確認してください。
  2. クラス名の代わりに、 のようなものEvalを指定する必要があります。packageName.classNameorg.test.Eval
于 2012-05-11T09:35:52.477 に答える