通过从Maven存储库中解析Tycho功能来构建p2存储库

时间:2014-11-20 18:08:23

标签: maven eclipse-plugin tycho

我正在尝试从部署在远程Maven存储库中的Tycho功能工件构建p2存储库,而不必首先将工件安装到本地Maven存储库中(如Tycho fails to resolve reference from product to eclipse-feature from a different reactor build中所述),并且没有在单个反应堆构建中一起构建所有功能和存储库。

背景

我有一个多模块Tycho项目,它构建了几个Eclipse插件和功能。

这样我就可以单独构建每个模块了 - 这样我就可以在Nexus Maven存储库中引用OSGI工件了 - 我在目标平台上启用了<pomDependencies>consider</pomDependencies>,并在模块之间添加了Maven依赖项或者存储库与<dependency/>元素一样的工件。

这很有效 - 我可以构建功能或运行插件测试,而不需要它们的相关插件可以在我的本地Maven存储库中,也可以在同一个反应器构建中。例如,当我在插件测试项目上运行mvn test时,相关的依赖项将从Nexus下载,Tycho将很乐意解决我的清单中的Import-Package,构建所有内容并运行测试。到目前为止一切都很好。

我想从这些功能生成一个p2存储库,以便我可以从更新站点在Eclipse中安装它们,并且广告化的方法是使用eclipse-repository打包类型。但是这里的计划失败了 - 在构建存储库时,Tycho似乎无法解决功能依赖关系,因为它可以在构建功能时解决插件依赖关系。所有尝试都会产生:

[ERROR] Cannot resolve project dependencies:
[ERROR]   Software being installed: my.eclipse.repository raw:0.0.1.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):0.0.1-SNAPSHOT
[ERROR]   Missing requirement: my.eclipse.repository raw:0.0.1.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):0.0.1-SNAPSHOT requires 'my.prj.eclipse.project.feature.feature.group 0.0.0' but it could not be found

我有两种方法成功构建了p2存储库:

  • 作为同一反应堆构建的一部分。如果我在Tycho多模块项目中创建eclipse-repository模块,并使用例如一次构建整个项目mvn verify,功能解析得很好。但我不想这样做。我更愿意单独构建模块。这意味着我们的CI可以为每个模块提供一个指标,我们可以立即看到哪些模块测试失败了;它为我们提供了并行构建的机会;并且我们避免必须在未更改的模块上不断运行构建。不得不使用单片Maven构建将是一种遗憾。
  • 如果我将Tycho项目安装到我的本地Maven存储库,则通过在依赖项上运行mvn install。但我也不想这样做,因为这意味着构建本质上是不可再生的,因为它会对本地存储库的状态敏感。我们的CI目前设置为每个作业维护一个Maven存储库,并在执行开始时完全擦除它,以保护我们免受这种潜在的混乱。

所以我的问题是:还有第三种方法吗?有没有什么方法可以让Tycho插件负责构建eclipse-repository打包类型以从远程Maven存储库下载功能?或者我可以从已经单独构建并部署到Maven存储库的插件构建p2存储库的任何其他方式?

我尝试过的事情包括:

  • 将Maven功能依赖指定为jareclipse-feature
  • 明确将功能添加到目标平台,例如

    ... <artifactId>target-platform-configuration</artifactId> <version>${tycho.version}</version> <configuration> <dependency-resolution> <extraRequirements> <requirement> <type>eclipse-feature</type> <id>my.prj.eclipse.project.feature</id> <versionRange>0.0.0</versionRange> </requirement> ...


我找到一个体面的解决方案的最接近的东西是一个多模块的Tycho项目,它只包含存储库和功能。

feature-project
 |- feature1    (eclipse-feature)
 |- feature2    (eclipse-feature)
 |- repository  (eclipse-repository)

构建此有效 - 添加到顶层POM的所有插件都是从Nexus下载的,可以包含在每个功能中并包含在生成的存储库中。

然而,这远非理想,因为我无法再将我的功能与我的插件一起存储在逻辑上;他们需要处于不同的项目层次结构中。尝试单独构建功能和存储库(例如mvn clean verify -pl :feature1,feature2,repository)可能会因Bug 380152而失败。

有更好的方法吗?我们将非常感激地提供任何帮助。

非常感谢


(顺便说一句:如果功能存在于本地Maven存储库中,则使用mvn clean verify -Dtycho.localArtifacts=ignore构建存储库将成功,并且不会向您显示工件正在解析的警告来自当地的回购......这是一个错误吗?)

1 个答案:

答案 0 :(得分:9)

你的全面分析让我印象深刻。您使用当前的Tycho版本(0.22.0)几乎可以获得所有可能的内容 - 除了非常不直观的解决方案,我不会期望任何人能够猜到它(见下文) )。但请注意,还需要一个小的修复,以使解决方案适用于SNAPSHOT工件。

但首先,我想为您观察到的内容提供一些技术(和历史)背景信息:

pomDependencies =仅适用于插件:此功能的用例是允许从Maven存储库引用插件(或更准确地说是OSGi包)。因此,当设置了标志并且项目依赖于JAR时,Tycho将检查它们是否是OSGi包,为它们即时生成p2元数据,并将它们添加到目标平台。对功能JAR没有类似的支持,因为这些通常不存在于Maven存储库中。

但是Tycho建造的项目怎么样?这些可以部署到Maven存储库中!是的,这是真的,这就是为什么我试图扩展pomDependencies概念以允许你想要做的事情。这个想法是每当Tycho考虑目标平台的POM依赖关系时,它还会检查p2索引文件...-p2metadata.xml...-p2artifacts.xml是否存在。然而,事实证明这会导致巨大的性能损失,因为Maven存储库服务器通常需要很长时间才能确定不存在工件。因此,远程下载被禁用,并替换为 local Maven存储库中的查找。通过这种方式,两个Tycho构建可以设置-Dtycho.localArtifacts=ignore,并且仍然可以通过本地Maven存储库交换POM中指定的工件。

了解这些实现细节,我们得到以下解决方案:您还需要向p2metadata和p2artifacts文件添加依赖项,而不是仅将存储库中的POM依赖项添加到功能工件中。例如:

<dependencies>
    <dependency>
        <groupId>myproject</groupId>
        <artifactId>myproject.feature</artifactId>
        <version>0.1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>myproject</groupId>
        <artifactId>myproject.feature</artifactId>
        <version>0.1.0-SNAPSHOT</version>
        <classifier>p2metadata</classifier>
        <type>xml</type>
    </dependency>
    <dependency>
        <groupId>myproject</groupId>
        <artifactId>myproject.feature</artifactId>
        <version>0.1.0-SNAPSHOT</version>
        <classifier>p2artifacts</classifier>
        <type>xml</type>
    </dependency>
</dependencies>

这使得Maven也下载了这些p2索引文件,因此Tycho将主要工件识别为Tycho工件。通过这种方式,您还可以通过POM依赖项将eclipse功能添加到目标平台中 - 至少几乎:使用0.22.0,存储库构建通过,但缺少feature.jar工件。我已经调试了这个问题,它是easy to fix

显然,每个实际依赖项的三个<dependency>元素的语法都不好。应该可以将其归结为单个p2artifacts元素 - 但这是更多的工作。如果您对此功能感兴趣,可以open an enhancement request in Tycho's issue tracker