Javassist使用OSGI在CtMethod.make和getDeclaredMethod中抛出notfound/null指针
javassist正在CtMethod.make com.company中抛出空指针。test是Activator和Joe的包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 {
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
的包