我正在尝试从部署在远程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存储库:
eclipse-repository
模块,并使用例如一次构建整个项目mvn verify
,功能解析得很好。但我不想这样做。我更愿意单独构建模块。这意味着我们的CI可以为每个模块提供一个指标,我们可以立即看到哪些模块测试失败了;它为我们提供了并行构建的机会;并且我们避免必须在未更改的模块上不断运行构建。不得不使用单片Maven构建将是一种遗憾。mvn install
。但我也不想这样做,因为这意味着构建本质上是不可再生的,因为它会对本地存储库的状态敏感。我们的CI目前设置为每个作业维护一个Maven存储库,并在执行开始时完全擦除它,以保护我们免受这种潜在的混乱。所以我的问题是:还有第三种方法吗?有没有什么方法可以让Tycho插件负责构建eclipse-repository
打包类型以从远程Maven存储库下载功能?或者我可以从已经单独构建并部署到Maven存储库的插件构建p2存储库的任何其他方式?
我尝试过的事情包括:
jar
和eclipse-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
构建存储库将成功,并且不会向您显示工件正在解析的警告来自当地的回购......这是一个错误吗?)
答案 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。