我正在使用第三方代码,它使用了一些jar(实际上,这是log4j)。运行我的插件时,我收到多个错误ClassNotFoundException
,NoClassDefFoundError
。由于第三方代码的使用仅限于某些ViewPart
,因此程序正在运行,但视图未实例化。
在Eclipse的编译时,我像往常一样将所需的jar添加到类路径中,并且代码在编译时没有任何错误,包括import
的{{1}}指令。
由于我将所有(许多)必需的jar放入项目目录的log4j
子目录中,我想修改lib
如下所示
build.properties
但显然这没有帮助。
在哪里可以看到我的整个捆绑/插件被打包打包以检查哪些罐子包含在那里?
更新
目前我把所需的罐子放了两次。
第一个 - 进入正常的Eclipse source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
lib/,\
.
窗口:
第二个 - 进入Configure Build Path
编辑器Classpath
标签的Runtime
部分:
后期配置在plugin.xml
文件中进行了以下更改:
build.properties
那么有可能自动这个怎么样?是否可以自动将所有传统的类路径条目传递给运行时?
我需要 SIMPLIFICATION ,我不想将jar包装成捆绑包和类似的东西。
问题是公开的。
答案 0 :(得分:4)
要导出插件,您可以使用文件菜单 - >出口 - >插件开发/可部署的插件和片段。然后选择你的插件,它将被导出为jar。要导出产品,.product
文件中有一个产品导出选项。
我建议您使用“新建项目”向导中的“现有JAR存档中的插件”选项创建单独的插件。如果是这样,那么我希望你不要忘记将它包含在你的运行配置中。另外,请查看this question了解详情。
<强>更新强> 您既不需要也不被迫将您的jar转换为bundle,但由于您没有创建纯Java项目(您有一个OSGI包,具有自己的类加载器和生命周期),您可能需要考虑一些最佳实践/规则,可以帮助您创建一个好的插件/项目。
为什么需要将依赖项转换为捆绑包?
你已经拥有了你的第三方依赖(log4j,apache commons 收藏等,)作为罐子,你需要做的就是把它添加到你的 捆绑类路径。这很简单,只要你工作就可以 只开发一个捆绑包或捆绑包不共享 的依赖关系。
但是,实际上,你可能会创建一堆捆绑包而且它们都是 会使用常见的依赖关系。这里的问题在于OSGi的方式 类加载工作。每个捆绑包都有自己的类加载器,所以如果你 有两个捆绑包都使用log4j作为jar依赖 classpath,当你尝试在每个bundle中引用log4j时, 每个人都会尝试创建自己的log4j类实例 他们各自的类加载器。这可能会导致类加载器约束 违规问题或ClassCastExceptions。如果你转换这些 依赖于OSGi包,那么这些问题就不再存在了 发生。这是因为现在每个依赖项(比如log4j)都有 它是自己的类加载器,所以无论你的Bundle A或Bundle B想要什么 加载log4j类,它将从log4j bundle classloader加载它。
有关详细信息,请参阅this article。
关于自动化过程:我认为不可能。由于您手动将jar添加到lib文件夹,因此您应该手动将它们添加到类路径中(在Runtime
部分中)。但是,在lib/
配置中定义build.includes
应该会有所帮助。此外,this可能会有所帮助。请注意,您不需要像通常那样“添加jar来构建路径”!将其添加到Runtime
部分(您的第二个屏幕截图)中,会将其添加到构建路径中。
此外,请注意,您的屏幕截图"."
不在Runtime
配置部分的顶部。
答案 1 :(得分:2)
log4j可用作OSGi包:http://ebr.springsource.com/repository/app/bundle/detail;jsessionid=66ADD0FE737BA9A5DD36A052F4A6809A.jvm1?name=com.springsource.org.apache.log4j。通常,如果您想使用尚未作为OSGi包发布的第三方库,那么检查SpringSource是否具有OSGi版本是值得的。
如果不是,你可以wrap it as a bundle yourself,正如亚历山大加夫里洛夫所暗示的那样。
最后,如果您真的想将其保留为非OSGi包,则需要在Bundle-ClassPath: ., lib/log4j.jar
中设置MANIFEST.MF
。当然,对于每个需要jar的插件,以及每个jar,以及在Eclipse中更改构建路径,都必须这样做。
一些更相关的问题和链接:https://stackoverflow.com/questions/5150415/log4j-under-osgi-eclipse-rcp,https://stackoverflow.com/questions/11341627/integrating-3rd-party-jars-into-eclipse-rcp,https://stackoverflow.com/questions/6545212/add-3rd-party-library-to-an-eclipse-plugin。
我需要简化,我不想将jar包装成捆绑包和类似的东西。
Bundles 是罐子,在MANIFEST.MF中有一些额外的信息,仅此而已。 OSGi(以及Eclipse)确实需要这些信息。最常用的库已经是bundle(只需检查MANIFEST.MF中的Bundle-SymbolicName
),或者作为bundle提供。如果不这样做,只需要为每个jar包装一个jar,而不必为每个依赖于jar的插件更改构建路径build.properties
和Bundle-ClassPath
。