Javassist使用OSGI在CtMethod.make和getDeclaredMethod中抛出notfound/null指针

Javassist使用OSGI在CtMethod.make和getDeclaredMethod中抛出notfound/null指针,java,reflection,osgi,javassist,Java,Reflection,Osgi,Javassist,javassist正在CtMethod.make com.company中抛出空指针。test是Activator和Joe的包 public class Activator implements BundleActivator { public Class<?> creerClasse() { CtClass toGenerateClass; ClassPool pool; pool = ClassPool.getDefault(); try {

javassist正在CtMethod.make com.company中抛出空指针。test是Activator和Joe的包

public class Activator implements BundleActivator {

public Class<?> creerClasse() {
    CtClass toGenerateClass;
    ClassPool pool;
    pool = ClassPool.getDefault();
    try {
        Class c;
        c = Class.forName("com.company.test.Joe");
        pool.appendClassPath(new ClassClassPath(c));
    } catch (ClassNotFoundException e1) {
        e1.printStackTrace();
    }

    pool.importPackage("com.company.test");

    toGenerateClass = pool.makeClass("Test118");

    try {
        toGenerateClass
                .addMethod(CtMethod
                        .make("public void afficher (com.company.test.Joe msg) { System.out.println(msg); } ;",
                                toGenerateClass));
    } catch (CannotCompileException e) {
        e.printStackTrace();
    }

    try {
        return toGenerateClass.toClass();
    } catch (CannotCompileException e) {
        e.printStackTrace();
        return null;
    }
}


public void start(BundleContext context) throws Exception {


        Class<?> genClass = creerClasse();
        Class<?> c = Class.forName("com.company.test.Joe");

        for (Method me : genClass.getDeclaredMethods()) { // test print, ok
            System.out.println(me);
        }

        Method method = genClass.getDeclaredMethod("afficher", c);

        Joe person = new Joe();
        person.setId(17);
        method.invoke(genClass.newInstance(), person);

}

}
公共类激活器实现BundleActivator{
公共级溪流(){
CtClass到GenerateClass;
类池池池;
pool=ClassPool.getDefault();
试一试{
丙级;;
c=Class.forName(“com.company.test.Joe”);
appendClassPath(新类路径(c));
}捕获(ClassNotFoundException e1){
e1.printStackTrace();
}
pool.importPackage(“com.company.test”);
toGenerateClass=pool.makeClass(“Test118”);
试一试{
toGenerateClass
.addMethod(CtMethod)
.make(“public void afficher(com.company.test.Joe msg){System.out.println(msg);};”,
toGenerateClass);
}捕获(不能编译异常e){
e、 printStackTrace();
}
试一试{
返回到GenerateClass.toClass();
}捕获(不能编译异常e){
e、 printStackTrace();
返回null;
}
}
public void start(BundleContext)引发异常{
类genClass=creerClasse();
c类=Class.forName(“com.company.test.Joe”);
对于(方法me:genClass.getDeclaredMethods()){//测试打印,确定
System.out.println(me);
}
方法方法=genClass.getDeclaredMethod(“afficher”,c);
乔人=新乔();
人.setId(17);
调用(genClass.newInstance(),person);
}
}
当我实例化pool时,pool=newclasspool(true); 它在getDeclaredMethod中抛出java.lang.NoClassDefFoundError:com/company/test/Joe。forName(“com.company.test.Joe”)将使用调用它的对象的类加载器。因此,在本例中,它将使用Activator类的类加载器。在OSGi中,类的类加载器通常是该类所在包的类加载器

捆绑包的类加载器只能加载捆绑包内的类以及其具有Import-Package语句的包中的类

因此,如果您想从任何包加载类,您不能简单地使用Class.forName。事实上,一个简单的类名在OSGi中甚至不是唯一的,因为不同的包可能提供不同版本的包


我不确定您的确切用例是什么。您使用固定字符串作为名称,但我猜您希望加载一个名称来自某个源(如配置)的类。如果你给我更多关于用例的信息,那么我可以推荐如何解决这个问题。

我解决了这个问题。在OSGi环境中,javassit池应该以这种方式初始化,以查找导入的类,而不是抛出
NullPointerException

    pool = new ClassPool(true);
    pool.insertClassPath(new LoaderClassPath(this.getClass()
            .getClassLoader()));
要使用生成的类并调用它的方法,应该以这种方式创建它

toGenerateClass.toClass(this.getClass()
                .getClassLoader(), getClass().getProtectionDomain());
不要忘记添加
PACKAGENAME
以动态加载从其他捆绑包导出的包


注:要导出软件包,请使用
PACKAGENAME

谢谢您的回答。实际上,我想动态生成一个类
a
,该类使用另一个捆绑包中的另一个类。在本例中,它是
com.company.test.Joe
该类将是类
a
中方法的参数,然后我将为
a
创建一个实例并调用该方法。我还在清单中添加了
导入包
动态导入包
,以及另一个捆绑包的
依赖项
,还从另一个捆绑包导出了包含
com.company.test.Joe
的包