Gradle 设置用于处理具有相同代码库但依赖项不同的两种部署类型



我正在开发一个新的Web应用程序项目,该项目必须在分布式环境中运行,以及一个很好的旧"将所有内容扔到战争文件中并在tomcat上运行"环境。 两个版本的代码完全相同,只有一个次要的 if/else 子句来处理不同的调用类型。

但是,我现在正在努力解决 gradle 设置。我有两个服务,我们称之为"DAO"和"连接器"作为示例。DAO 使用连接器从数据源检索数据。 在分布式模式下,DAO 必须在 Connector:api 上降级,因为 DAO 应该只知道所述 API,因为实现在其他地方运行。 在捆绑模式下,DAO必须依赖于Connector:bundle,因为所有内容都必须进入一个war文件。

我们生产的所有 jar 都使用 maven-publish 插件在我们的内部 nexus 3 服务器上发布。我们目前使用的是 gradle 4.10.3 版本,DAO 项目是更大的多项目设置的一部分,由紧密耦合的模块组成,而连接器是供另一个应用程序使用的共享服务。

为了完成这些事情,我尝试了许多想法。他们中的大多数都是完全错误的,所以我不会在这里谈论它们。我现在最终得到的是一个多发布设置。

publishing {
publications {
dist(MavenPublication) {
alias false
from components.java
afterEvaluate {
artifact apiJar
}
}
bundle(MavenPublication) {
alias true
from components.java
afterEvaluate {
artifactId "${artifactId}-bundle"
}
}
}
repositories {...}
}

此设置现在生成 2 组 pom 和 jar 文件。一个用于连接器 api.jar一个用于连接器捆绑.jar

在 DAO 依赖项设置中,我现在必须使用 if 块来决定要设置的依赖项:

gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(generatePomFileForBundlePublication)){
dependencies {
implementation "com.example:Connector-bundle:1.0.0"
}
}
else {
dependencies {
implementation "com.example:Connector:1.0.0:api"
}
}
}
}

但是,这会导致我在开发时不再有可用的库的问题。所以我无条件地添加了 API 依赖项。

这确实有些工作,但现在生成的 pom 文件总是在里面有 API 依赖项,当我构建捆绑版本时,它有两个依赖项。

因此,在完成了这个冗长的解释之后,这是我的问题:
有没有更好的方法来代替这个......拼凑? 如果没有,我至少可以处理依赖复制问题吗?当我构建捆绑版本时,我不希望拥有 API 包。它充其量是冗余的,最坏的情况是它增加了更多的冗余依赖项。我不能像上面说的那样有条件地添加它,因为我失去了针对 API 进行开发的能力,而且我不想一直手动添加和删除它。

任何帮助都值得赞赏,因为我只是没有想法。

PS:别名的使用是为了处理在多项目环境中使用多发布在 maven-publish 插件中的问题(见 https://github.com/gradle/gradle/issues/1061(

好的,在放弃了我所有的先入之见并创建了一个 gradle 原型之后,我找到了一个可行的解决方案。这是我所做的:

首先,我在gradle.propertiesmode=dist中添加了一个新属性,
这使我能够通过if(mode == "dist"(else块来拆分我的依赖项。举个例子:

dependencies {
if (mode == "dist"){
implementation "com.example:Connector:1.0.0:api" 
} else {
implementation "com.example:Connector-bundle:1.0.0"
}
}

多亏了这种设置,gradle 现在默认就像我处于分发模式一样,这意味着我总是加载 API 库,而不是完整的东西。

接下来,我创建了一个自定义任务publishBundle,在其中设置mode = "lib">并执行整个构建和发布过程。举个例子:

task publishBundle {
mode = "lib"
dependsOn "build"
dependsOn "publishBundlePublicationToNexusRepository"
}

最后一次调整必须在发布配置中进行。在这里,我还必须添加正确的模式值:

publishing {
publications {
dist(MavenPublication) {
mode = "dist"
alias false
from components.java
afterEvaluate {
artifact apiJar
}
}
bundle(MavenPublication) {
mode = "lib"
alias true
from components.java
afterEvaluate {
artifactId "${artifactId}-bundle"
}
}
}
repositories {...}
}

这样,正常的构建和发布过程将遵循分布式方法,而publishBundle任务将创建和发布捆绑包。在我们的存储库中,我们现在有两个连接器项目:连接器和连接器捆绑包,这意味着我们可以根据我们所处的模式处理不同的依赖项。

这仍然感觉像是拼凑,但我可以想象我的要求太......特殊。

最新更新