1

在一个 Eclipse 插件项目中,我有一个 jar 文件,我想从中加载类和调用方法。这些 jars 添加到清单文件的捆绑类路径中。如何加载这些类运行时,如果我尝试使用 urlclassloader 我得到 java.lang.NoClassDefFoundError 但我确定类在那里。我阅读了基于 Eclipse osgi 并使用它自己的类加载器,因此我可能会收到此错误。但为什么 ?有人对我的问题有很好的解释和实用的解决方案吗?谢谢你。

4

2 回答 2

3

这是由 OSGi 的不同类加载机制引起的问题。首先,检查您是否在清单中添加了正确的导入声明。如果导入是正确的(并且具有正确的版本),它们可能不可见,因为您使用的 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的更多信息

于 2013-03-13T13:36:32.820 回答
0

我遇到了类似的问题,这是我的解决方案。可能有点晚了,但我希望它能帮助其他有同样问题的人。

我注意到来自 eclipse (osgi) 的类加载器不会加载完整的 jar。它只加载通过直接加载的类classloader.load(classname)所以我只是用这个问题的代码读取了 jar 中包含的所有类名,并通过调用显式遍历所有类名classloader.load(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();

希望这可以帮助。

于 2015-03-13T06:38:08.380 回答