【问题标题】:How to add conventional jar into plugin (ClassNotFoundException, NoClassDefFoundError)?如何将常规jar添加到插件中(ClassNotFoundException,NoClassDefFoundError)?
【发布时间】:2014-01-30 20:27:51
【问题描述】:

我正在使用第三方代码,它使用了一些 jar(实际上,这是 log4j)。运行我的插件时,我收到多个错误ClassNotFoundExceptionNoClassDefFoundError。由于第三方代码使用仅限于一些ViewPart,所以程序正在运行,但视图没有实例化。

在 Eclipse 的编译时,我像往常一样将所需的 jar 添加到类路径中,并且代码在编译时没有任何错误,包括 log4jimport 指令。

由于我将所有(许多)所需的 jar 放入项目目录的 lib 子目录中,我想修改 build.properties 如下

source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
               META-INF/,\
               lib/,\
               .

但这显然没有帮助。

我在哪里可以看到我的整个捆绑包/插件已编译打包以检查其中包含哪些 jar?

更新

目前我放了两次所需的罐子。

第一个 -- 进入普通的 Eclipse Configure Build Path 窗口:

第二个——进入Runtime标签的Classpath部分plugin.xml编辑器:

后一个配置在build.properties 文件中进行了以下更改:

source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
               META-INF/,\
               lib/,\
               .,\
               lib/java-getopt-1.0.13.jar,\
               lib/jsp-api-2.0.jar,\
               lib/junit-4.11.jar,\
               lib/log4j-1.2.17.jar,\
               lib/rhino-1.7R4.jar,\
               lib/servlet-api-6.0.36.jar,\
               lib/tomcat-catalina-7.0.42.jar,\
               lib/commons-logging-1.1.3.jar,\
               lib/spring-beans-3.2.0.RELEASE.jar,\
               lib/spring-core-3.2.0.RELEASE.jar,\
               lib/miglayout-core-4.2.jar,\
               lib/miglayout-swt-4.2.jar,\
               conf/

那么有可能以某种方式自动化吗?是否可以自动将所有常规类路径条目传递给运行时?

我需要简化,我不想将罐子包装成束之类的东西。

问题是开放的。

【问题讨论】:

    标签: java eclipse jar eclipse-rcp eclipse-plugin


    【解决方案1】:

    要导出插件,您可以使用文件菜单 -> 导出 -> 插件开发/可部署插件和片段。然后选择你的插件,它将被导出为一个 jar。要导出产品,.product 文件中有一个产品导出选项。

    我建议您使用“新建项目”向导中的“来自现有 JAR 档案的插件”选项创建一个单独的插件。如果是这样,那么我希望您不要忘记将它包含在您的运行配置中。另外,请查看this question了解更多详情。

    更新: 您既不需要也不需要将 jar 转换为包,但由于您没有创建纯 Java 项目(您有一个 OSGI 包,具有​​自己的类加载器和生命周期),您可能需要考虑一些最佳实践/规则,可以帮助您创建一个好的插件/项目。

    为什么需要将依赖项转换为捆绑包?

    您已经拥有第三方依赖项(log4j、apache commons 收藏等,)作为罐子,你需要做的就是将它添加到你的 捆绑类路径。这很简单,只要你是 仅开发一个捆绑包或您的捆绑包不共享 依赖关系。

    但是,实际上,您可能会创建一堆捆绑包,并且它们都 将使用公共依赖项。这里的问题在于 OSGi 类加载工作。每个包都有它自己的类加载器,所以如果你 有两个捆绑包都使用 log4j 作为 jar 依赖项 类路径,当您尝试在每个包中引用 log4j 时, 每个人都会尝试在其中创建自己的 log4j 类实例 他们各自的类加载器。这可能会导致类加载器约束 违规问题或 ClassCastExceptions。如果你转换这些 依赖于 OSGi 包,那么这些问题将不再 发生。这是因为现在您的每个依赖项(例如 log4j)都有 它是自己的类加载器,因此每当您的 Bundle A 或 Bundle B 想要 加载 log4j 类,它将从 log4j 捆绑类加载器加载它。

    更多信息请参考this article

    关于自动化过程:我认为这是不可能的。由于您手动将 jars 添加到 lib 文件夹中,因此您应该手动将它们添加到类路径(在 Runtime 部分)。但是,在 build.includes 配置中定义 lib/ 应该会有所帮助。另外,this 可能会有所帮助。请注意,您不需要像往常那样“将 jar 添加到构建路径”!将其添加到 Runtime 部分(您的第二个屏幕截图),将为您将其添加到构建路径中。

    另外,请注意,在您的屏幕截图中,"." 不在Runtime 配置部分的顶部。

    【讨论】:

    • 我还没有product。另外我不明白为什么要先打包?我正在编写 Java 代码,为什么我不能使用 jars?
    • 感谢您为罐子制作单独的捆绑包,但我已经制作了一些代码,并希望将其包装进去。它具有正常的常规依赖项。这些是对外部 jar 和整个外部项目的依赖。 Eclipse 也允许在插件项目中添加两者。但我不明白为什么 Eclipse (1) 允许它们并且 (2) 忽略它们。如果 Eclipse 要么禁止条目,要么使用它们,那就太好了。拥有未使用的功能是没有意义的。
    • 插件项目仍然是一个 Eclipse 项目,所以我相信这就是为什么它允许与其他项目相同的操作。此外,具有相同结构的项目可能会以不同的方式构建,具体取决于项目类型、构建器、方面等。所以,不太确定,为什么它会让你如此困惑。每个项目都应该进行适当的配置,你只需要忍受它;)
    • 如果它允许将 jars 添加到 Build Path 那么为什么它在构建时不使用它们?
    • 因为构建过程是自定义的,正如我之前提到的,取决于许多因素。构建 .war 有一种方法,构建 .ear 有另一种方法,构建 eclipse 插件也不同。此外,Build Path 只是为了让 eclipse 能够预编译您的项目,协助自动完成、内容助手、搜索等,它不是为不同类型的容器(Web 服务器、eclipse-rcp)创建工件的信息构架)。从来没有。即使使用 Maven,您也可以为项目指定依赖项,然后根据需要单独配置工件的构建。
    【解决方案2】:
    1. log4j 以 OSGi 包的形式提供:http://ebr.springsource.com/repository/app/bundle/detail;jsessionid=66ADD0FE737BA9A5DD36A052F4A6809A.jvm1?name=com.springsource.org.apache.log4j。一般来说,如果您想使用尚未发布为 OSGi 捆绑包的第三方库,则值得检查 SpringSource 是否具有 OSGi 版本。

    2. 如果不是,您可以按照 Alexander Gavrilov 的建议wrap it as a bundle yourself

    3. 最后,如果你真的想把它作为一个非 OSGi 包,你需要在你的MANIFEST.MF 中设置Bundle-ClassPath: ., lib/log4j.jar。当然,对于需要 jar 的每个插件、每个 jar 以及更改 Eclipse 中的构建路径,都必须这样做。

    一些更相关的问题和链接:https://stackoverflow.com/questions/5150415/log4j-under-osgi-eclipse-rcphttps://stackoverflow.com/questions/11341627/integrating-3rd-party-jars-into-eclipse-rcphttps://stackoverflow.com/questions/6545212/add-3rd-party-library-to-an-eclipse-plugin

    我需要简化,我不想将罐子包装成捆绑包之类的东西。

    Bundles jars,在 MANIFEST.MF 中有一些额外的信息,仅此而已。 OSGi(以及因此的 Eclipse)确实需要这些信息。最常用的库要么已经是捆绑包(只需检查 MANIFEST.MF 中的Bundle-SymbolicName),要么作为捆绑包提供。如果做不到这一点,则只需为每个 jar 包装一次 jar,而不必为依赖于 jar 的每个插件更改构建路径 build.propertiesBundle-ClassPath

    【讨论】:

    • 我不明白,为什么它启用了以Eclipse标准方式添加jar呢?以后就忽略吧?
    • 可能是因为没有简单的方法可以禁用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2014-11-26
    相关资源
    最近更新 更多