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);
}
}
当我使用pool实现池= new ClassPool(true); 它在getDeclaredMethod中抛出java.lang.NoClassDefFoundError:com / company / test / Joe
答案 0 :(得分:0)
Class.forName(&#34; com.company.test.Joe&#34;)将使用从中调用的对象的ClassLoader。因此,在这种情况下,它将使用Activator类的ClassLoader。在OSGi中,类的ClassLoader通常是Class所在的bundle的ClassLoder。
bundle的ClassLoader只能加载bundle中的类和包含它的Import-Package语句的包中的类。
因此,如果要从任何包中加载Class,则不能简单地使用Class.forName。事实上,一个简单的类名在OSGi中甚至不是唯一的,因为不同的bundle可能会提供不同版本的包。
我不确定您的确切用例是什么。你使用一个固定的字符串作为名称,但我想你想加载一个名称来自某些来源的类,如配置。如果你给我更多关于用例的信息,那么我可以推荐如何处理这个问题。
答案 1 :(得分:0)
我解决了这个问题。在OSGi环境中,应该以这种方式初始化javassit池以查找导入的类而不是抛出NullPointerException
。
pool = new ClassPool(true);
pool.insertClassPath(new LoaderClassPath(this.getClass()
.getClassLoader()));
并使用生成的类并调用它的方法,它应该以这种方式创建
toGenerateClass.toClass(this.getClass()
.getClassLoader(), getClass().getProtectionDomain());
不要忘记添加<DynamicImport-Package>PACKAGENAME</DynamicImport-Package>
以动态加载其他包中的导出包。
PS:导出包使用<Export-Package>PACKAGENAME</Export-Package>