2013-03-13 84 views
1

在eclipse插件项目中,我有一个jar文件,我想从中加载类和调用方法。这些jar被添加到清单文件中的bundle classpath中。如何加载这些类运行时,如果我尝试与urlclassloader我得到java.lang.NoClassDefFoundError但我相信类是在那里。我读过基于eclipse的osgi并使用它自己的类加载器,并且可能因此导致此错误。但为什么 ?有没有人对我的问题有一个很好的解释和实际的解决方案? 谢谢。eclipse插件类加载错误

+1

第一个实用的解决方案是停止使用URLClassLoader。为什么在那里? – 2013-03-13 13:39:06

回答

3

这是由OSGi的不同的类加载机制引起的问题。 首先,检查是否将正确的导入声明添加到了manifest。 如果导入是正确的(并且版本正确),它们可能不可见,因为您正在使用的JAR没有导出所需的类。 OSGi只能看到导出的类。 使用Eclipse,这意味着您使用Equinox作为OSGi实现,您可以使用Eclipse-Buddy-Classloading。 使用JAR创建一个新项目并导出所有内容。现在将其注册为主包的伙伴 - 主包现在可以看到提供包的每个类。

请记住,在OSGi中使用类加载器是'邪恶'。班级无法通过完全合格的班级名称来识别。

看看OSGi的核心规范关于OSGi类加载(osgi.org)和http://rajakannappan.blogspot.de/2010/03/eclipse-classloading-and-buddy-policy.html

0

我有一个类似的问题,这里是我的解决方案的更多信息。这可能有点晚,但我希望它能帮助其他人解决同样的问题。

我注意到eclipse(osgi)的类加载器没有加载完整的jar。它只加载通过classloader.load(classname)直接加载的类。所以我只读了包含在jar中的所有类名,代码为this question,并通过调用显式classloader.load(classname)来遍历所有className。下面是我管理的方式示例:

private void loadClasses(final File jar) { 
    final URL url = new URL("jar", "", "file:" + jar.getAbsolutePath() + "!/"); 
    final List<String> classNames = getAllClassNames(jar); //Code from above link in this method 
    final URLClassLoader classloader = new URLClassloader(url, this.getClass().getClassLoader()); 
    for (String className : classNames) { 
     classLoader.load(className); 
    } 
} 

如果你想实例化一个类你可以做到这一点与

final Class<?> clazz = classLoader.load(className); 
final T type = (T)clazz.newInstance(); 

希望这有助于。