在 Eclipse RCP Tycho 应用程序中使用第三方库

Using third-party libraries in Eclipse RCP Tycho app

我已经按照 vogella 广泛的第谷教程创建了一个样板项目。

事实:

问题:

问题:

相关解决方案:

我认为你有一个根本性的误解。

Maven:Maven 通过 pom.xml 确定所有项目依赖关系并自动解决传递依赖关系(假设所有 pom 文件和工件都存在于存储库中您已经配置并正确声明了它们的依赖关系)。

Tycho: 问题是Eclipse已经有自己的基于产品文件、feature.xml文件和插件MANIFEST.MF文件的项目模型. Tycho 利用 Eclipse 的 Maven 机制,但其想法是 pom.xml 文件仅配置 Maven 插件并声明打包类型。这为 Maven 提供了一个入口点,但随后 Tycho 接管了它。虽然 Maven 通常会根据 pom.xml 文件中的信息构建依赖链,但 Tycho 正在根据产品、功能和 MANIFEST.MF 文件中的信息构建依赖项更改。您不要在 pom.xml 文件中放置任何依赖项。 Tycho 还使用 Eclipse p2 存储库(而不是普通的 Maven 存储库)来查找在本地模块或目标平台中找不到的依赖插件。

这对许多 Eclipse 开发人员来说实际上是一个好处,因为他们已经在他们的 Eclipse 插件、特性和产品中正确设置了所有内容。他们不想重复 pom.xml.

中的所有依赖项

在 Eclipse 插件中使用库:在 Eclipse 中,如果您想使用尚未打包为 Eclipse 插件的库,您有几个选择.您的插件可以在 libs 文件夹中包含一组 JAR,然后在插件和 运行time 类路径中包含该 libs 文件夹(请参阅 build.properties 文件)。另一种选择是创建您自己的 "library plug-in",将 JAR 库重新打包为 Eclipse 插件。另见 https://wiki.eclipse.org/FAQ_What_is_the_classpath_of_a_plug-in%3F。这就是你得到的答案。

问题是,如果您尝试包含一个包含多个 JAR 的复杂库,这些 JAR 是正常分布的,并且通过 Maven 包含在标准 Java 项目中。我们在我的项目中使用 Jersey JAX-RS 实现遇到了这个问题。没有 p2 存储库包含库的所有部分作为具有正确依赖信息的插件。

Easy Solution:如果需要公共库,先查看Orbit项目,看是否已经打包为Eclipse插件,http://www.eclipse.org/orbit/ .在这种情况下,您可以下载它们并将它们包含在您的目标平台中,或者您可以在 (Tycho) 构建时从它们的 p2 存储库中动态拉入它们。您的插件将只包含这些插件作为依赖项(在它们的 MANIFEST.MF 文件中)。

解决方法/解决方案:在我们的例子中,Jersey JAX-RS 不能作为 Eclipse 插件使用,它有一堆传递依赖项。解决方法是像我上面提到的那样用两个 pom 文件创建一个 Eclipse "library plug-in"。我们最初创建了一个带有 libs 文件夹的框架插件。一个 pom 文件只是一个带有 <packaging>jar</packaging> 的标准 Maven pom 文件,它声明了引入 Jersey JAX-RS 实现及其所有依赖项所需的顶级依赖项。依赖项使用 <scope>compile</scope> 声明。我们使用 maven-dependency-plugin 将所有这些依赖项复制到项目的 libs 文件夹中。

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>compile</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>libs</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

我们实际上结束了 运行Ning Maven 时不时地用那个 pom 手动更新库,然后我们检查插件及其所有依赖的 JAR进入源代码控制。 稍后检查构建,我发现我们实际上在开始构建的 Maven/Tycho 部分之前使用 Maven 和单独的构建任务实时填充 libs 文件夹。当然,插件的 MANIFEST-MF 文件的 Bundle-ClassPath 和 Export-Package 条目直接来自源代码控制。我们必须不时检查它们以确保它们与我们从 Maven 获得的库和包相匹配。 (除非我们提升主要库版本或在 Maven 级别添加新的依赖项,否则这不会有太大变化。)插件的 build.properties 将 libs/ 文件夹作为 bin.includes 的一部分。

在开发环境中,在我们第一次检查代码后,我们只是在项目的 "copy dependencies" pom 上 运行 mvn(使用外部工具启动配置,该配置也已与项目一起检查)文件。这将使用所有 JAX-RS 库和依赖项填充 libs 文件夹。当我们更新有关依赖项的某些内容时,或者当我们在具有不同版本的 JAX-RS 依赖项的分支之间跳转时,我们只需要再次 运行 它。我们设置 .gitignore 以确保我们不会将库提交给 Git.

此项目的另一个 pom 设置为 <packaging>eclipse-plugin</packaging> 的普通 Tycho pom 文件。在我们的自动构建过程中,我们 运行 在构建过程的早期(就在签出之后)一步调用带有 jar pom 的 mvn 来填充库。然后我们使用 eclipse-plugin pom 继续主要 Maven/Tycho 构建。 eclipse-plugin pom 没有依赖信息(正如我上面所说的)。它只是为 Tycho 提供了一种识别 Eclipse 插件并根据其 MANIFEST.MF 和 build.properties 文件构建它的方法。但是内置的插件包括并公开了所有那些由对 jar pom 步骤的 mvn 调用填充的库。

所以,有点乱,但这是我们几年前遇到这个问题时找到的最佳解决方案。我不确定 Tycho 是否正在做任何工作来允许某种混合 Maven/Tycho 构建,它可以作为构建的一部分自动执行此操作。我想我应该问开发商。 :)

你的问题

  • 在哪里添加依赖?我的项目中没有jar包的pom。 答:上面的解决方法可以让你用一个项目来完成。您只有两个 pom 文件,例如 pom_deps.xml 和 pom.xml。您只需单独调用 pom_deps.xml 来填充 libs 文件夹(在开发环境中和您的自动构建中)。
  • 我应该用必要的 JAR 创建一个单独的项目吗?我如何将这种依赖关系包含到我的整个项目中? 答:我上面描述的解决方法让您可以在单个项目中完成。另一种方法是创建一个单独的 JAR 项目,但我认为您的 Eclipse RCP 应用程序无法真正以有用的方式包含 <packaging>jar</packaging> 模块。我发现这样做的唯一方法是使用类似的解决方法。您首先构建 JAR 模块,将其安装到 Maven 存储库中,然后让您的插件项目之一将 JAR 捆绑在其 libs 文件夹中。 (如果你真的想那样做,问。我们有一个案例,我们也必须这样做,我可以提供我们在开发和构建中所做的步骤以使其工作。我认为单一项目解决方法我上面提供的对你的情况更有意义。)
  • 为这个 RCP 应用程序创建一个单独的插件和一个功能真的是一个很好的做法吗?回答:那真的是一个单独的问题。如果您有一个包含多个插件的功能,您也会遇到同样的问题。 Tycho 可以处理 product/feature/plug-ins,但它不能跳转到基于 Maven 的依赖项解析。您最终将不得不使用相同的解决方法

总结:根本问题是Eclipse插件不能"see"一个裸JAR库。该插件需要将库包含在其本地 libs 文件夹中(在 MANIFEST.MF 中具有匹配的 Bundle-ClassPath 条目),或者它需要依赖于导出适当包的其他一些插件。 Tycho 只是通过 Eclipse 插件来解决依赖关系,它不能直接利用正常的 Maven 依赖关系解析来拉入一堆 JAR。如果您所有的依赖项都已经是插件,那很好。如果没有,您可能必须使用上面的解决方法来打包一组库供您的插件使用。

只需将插件添加到 pom 依赖项并在 target-platform-configuration 的配置中包含条目 <pomDependencies>consider</pomDependencies> 即可。

<plugins>
    <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>target-platform-configuration</artifactId>
        <version>${tycho.version}</version>
        <configuration>
            <!-- The configuration to make tycho consider the maven dependencies -->
            <pomDependencies>consider</pomDependencies> 
            <!-- other configurations -->
        </configuartion>
    </plugin>
    <!-- other plugins-->
</plugins>
<dependencies>
    <!-- An example third-party bundle (plugin) present in maven repository-->
    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.gogo.shell</artifactId>
        <version>1.1.0</version>
    </dependency>
</dependencies>

引用 link here.