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

14

我按照vogella详尽的Tycho教程创建了一个样板项目。

enter image description here

事实:

  • 没有特性(feature),也没有插件。唯一的插件是RCP应用程序,也是入口点。

问题:

  • 我不知道在哪个pom.xml文件中包含第三方依赖关系。

  • 不能将它们包含在RCP项目中,因为该POM的打包方式是eclipse-plugin而不是jar。从我注意到的情况来看,如果我将打包方式更改为jar,则"Maven Dependencies"库将自动添加。如果我更改回eclipse-plugin,它们将被删除。

问题:

  • 我在哪里添加依赖?我的项目中没有包含jar打包的pom。
  • 我应该创建一个包含必要JAR的单独项目吗?如何将该依赖项包含到整个项目中?
  • 为这个RCP应用程序创建一个单独的插件和特性真的很好吗?

相关解决方案:

  • "更新项目"无效,其他SO问题的n个解决方案也无效。
  • 还有这个问题那个问题,但我不完全理解答案。

你在谈论什么依赖关系?第三方库?最简单的方法是将它们包含在项目类路径中,并在build.properties文件中要求在构建时“包含它们”(通过插件编辑器双击plugin.xml时)。如果您需要eclipse-plugin依赖项,也可以使用插件编辑器添加它们。同时,您在谈论maven,您是否使用maven的tycho插件?如果是这样,maven与tycho插件一起使用将使用您的plugin.xml/manifest/build.properties...文件来构建您的插件。 - titou10
1
每个插件都应该有一个关联的MANIFEST.MF文件,通常在其中会提到依赖关系。 - SomeDude
@titou10 我不想手动添加依赖项...我正在使用Maven+Tycho。我只是不知道应该在哪个项目的哪个pom.xml文件中添加这些依赖项。 - Georgian
不太清楚你的问题。根据其他问题的链接,我猜测是非OSGi捆绑包导致了你的问题?你能给出一个你想要包含的库的具体例子吗? - Jonah Graham
2个回答

22
我认为你有一个基本的误解。
Maven:Maven通过pom.xml确定所有项目依赖关系并自动解决传递依赖关系(假设您配置了所有pom文件和工件存在于正确声明其依赖关系的存储库中)。
Tycho:问题在于Eclipse已经拥有基于产品文件,feature.xml文件和插件MANIFEST.MF文件的自己的项目模型。Tycho利用Maven机制来构建Eclipse,但是pom.xml文件仅配置Maven插件并声明打包类型。这为Maven提供了一个入口点,然后Tycho接管。虽然Maven通常会从pom.xml文件中的信息构建依赖关系链,但Tycho正在从产品、功能和MANIFEST.MF文件中的信息构建依赖关系链。您不需要在pom.xml文件中放置任何依赖项。Tycho还使用Eclipse p2存储库(而不是普通的Maven存储库)来查找未在本地模块或目标平台中找到的依赖插件。
对许多Eclipse开发人员来说,这实际上是一个好处,因为他们已经在他们的Eclipse插件、特性和产品中正确设置了所有内容。他们不想在pom.xml中重复所有依赖项。
在Eclipse插件中使用库:如果您想要使用未打包为Eclipse插件的库,您有几个选项。您的插件可以在libs文件夹中包含一组JAR,并将该libs文件夹包含在插件和运行时类路径中(请参见build.properties文件)。另一种选择是创建自己的“库插件”,将JAR库重新打包为Eclipse插件。还可以参见https://wiki.eclipse.org/FAQ_What_is_the_classpath_of_a_plug-in%3F。这就是您在上面得到的答案。
问题是,如果您要包含一个具有多个JAR的复杂库,通常通过Maven在标准Java项目中分发和包含,则会遇到问题。我们在我的项目中使用Jersey JAX-RS实现时遇到了这个问题。没有p2仓库包含所有库的组件作为正确依赖项的插件。

简单解决方案: 如果您需要一个通用库,请首先检查Orbit项目,看看这些库是否已经被打包为Eclipse插件,http://www.eclipse.org/orbit/。在这种情况下,您可以下载它们并将其包含在您的目标平台中,或者您可以从它们的p2存储库在(Tycho)构建时动态地拉取它们。您的插件只需将这些插件作为依赖项包含在其中(MANIFEST.MF文件)。

解决方案/解决方法: 在我们的情况下,Jersey JAX-RS不可用作Eclipse插件,并且它有许多传递依赖关系。解决方法是创建一个像我上面提到的Eclipse“库插件”,其中包含两个pom文件。我们最初创建了一个带有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>

实际上,我们不时地手动使用该pom来运行Maven以更新库文件,然后将插件及其所有依赖的JAR文件一起检入源代码管理工具。在稍后检查构建时,我发现我们实际上会在开始Maven/Tycho构建之前使用一个单独的构建任务通过Maven动态地填充libs文件夹。当然,插件的MANIFEST-MF文件的Bundle-ClassPath和Export-Package条目直接来自源代码管理工具。我们需要不时地检查它们以确保它们与我们从Maven获取的库和包匹配(除非我们升级主要库版本或在Maven级别添加新的依赖项,否则这不会经常更改)。插件的build.properties文件将libs/文件夹作为bin.includes的一部分。
在开发环境中,我们首先检出代码后,只需在项目的“copy dependencies”pom文件上运行带有外部工具启动配置(也与项目一起检入)。这将使用所有JAX-RS库和依赖项填充libs文件夹。只有当我们更新依赖项的某些内容或在不同版本的JAX-RS依赖项的分支之间跳转时,我们才需要再次运行它。我们设置.gitignore以确保我们不会将libs提交到Git。
此项目的另一个pom设置为普通的Tycho pom文件,其中eclipse-plugin。在我们的自动化构建过程中,我们在构建过程的早期阶段(在检出后)运行一步,调用mvn与jar pom一起填充libs。然后,我们使用eclipse-plugin pom继续进行主要的Maven/Tycho构建。eclipse-plugin pom没有依赖信息(如我上面所说)。它只是提供给Tycho一种识别Eclipse插件并基于其MANIFEST.MF和build.properties文件构建它的方法。但是构建的插件包括并公开了通过对jar pom步骤的mvn调用填充的所有那些libs。
因此,虽然有点混乱,但这是我们几年前在遇到这个问题时找到的最佳解决方案。 我不确定Tycho是否正在进行任何工作以允许某种混合Maven / Tycho构建,可以自动完成构建的一部分。 我想我应该问开发人员。 :) 您的问题:
  • 我应该在哪里添加依赖项?我的项目中没有带有jar包装的pom文件。 答案:上述解决方法可以让您在一个项目中完成。您只需要两个pom文件,例如pom_deps.xml和pom.xml。您只需单独调用pom_deps.xml以填充libs文件夹(在开发环境和自动化构建中)。
  • 我应该创建一个带有必要JAR的单独项目吗?如何将该依赖项包含到整个项目中? 答案:我描述的解决方法可以让您在一个项目中完成。另一种方法是创建一个单独的JAR项目,但我认为您的Eclipse RCP应用程序无法以有用的方式包含<packaging>jar</packaging>模块。我找到的唯一方法是使用类似的解决方法。首先构建JAR模块,将其安装到Maven存储库中,然后让您的插件项目之一在其libs文件夹中捆绑JAR。(如果您真的想这样做,请询问。我们也有这样的情况,我可以提供我们在开发和构建中所做的步骤来使其正常工作。我认为我提供的单个项目解决方法对您的情况更有意义。)
  • 为这个RCP应用程序创建一个单独的插件和功能真的是一种好习惯吗? 答案:那确实是一个单独的问题。如果您有一个包含多个插件的功能,则会遇到同样的问题。Tycho可以处理产品/功能/插件,但它无法跨越基于Maven的依赖关系解析。您最终将不得不使用相同的解决方法。
摘要: 根本问题在于Eclipse插件无法“看到”裸的JAR库。插件需要将库包含在其本地libs文件夹中(在MANIFEST.MF中具有匹配的Bundle-ClassPath条目),或者它需要依赖于导出适当包的其他插件。Tycho只通过Eclipse插件解决依赖关系,不能直接利用正常的Maven依赖关系解析来拉取一堆JAR。如果所有的依赖都是插件,那么就没问题了。如果不是,你可能需要使用上面的解决方法为你的插件打包一组库来使用。

你好 :) 你的帖子似乎是我在这个话题上看到的最实质性的。你有什么例子可以分享一下你是如何做到的吗?我能看到的限制之一是如何将整个目录添加到 .classpath / MANIFEST.MF 中。我认为它们必须引用特定的文件,例如? - Jakg
build.properties可以引用文件夹,例如bin.includes = META-INF/,\ .,\ libs/你说得对,MANIFEST.MF的Bundle-ClassPath引用了单独的JAR。在我运行maven任务重新构建插件并拉取最新的传递依赖项之后,我只需转到Eclipse中的项目。我删除所有运行时依赖项。然后我添加...,并多选libs文件夹中的所有内容。导出的包也是如此。这是一些手动步骤,但只需要一分钟。你的情况可能有所不同,但对我们有效。 - Tom Bryan
我还应该注意到,在“pomDependencies”可用之前(或者至少在我们当时使用的Tycho版本中),我就已经写下了那个回答。下面@Loganathan回复中的链接可能是今天更好的方法。 - Tom Bryan
哦,我们实现这个功能的项目是在我公司之外可用的一个工作项目。如果“pomDependencies”方法真的不适合您,请告诉我,我会看看是否可以在GitHub上为您发布一个骨架示例。 - Tom Bryan

1
只需将插件添加到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>

参考链接 here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接