You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle(Liferay工作区)复制JAR异常,如何正确复制当前构建模块JAR?

解决方案:Liferay多模块项目集中复制目标模块最终JAR

问题根源

你当前的脚本绑定在Jar任务的doLast阶段,而Liferay的OSGi模块构建中,Jar任务仅生成基础JAR包,后续assemble任务还会对JAR进行额外处理(比如注入OSGi元数据、合并资源、签名等),此时复制的是未完成最终处理的中间产物,导致体积和build/libs中的最终JAR不一致。

推荐实现方式

将复制逻辑绑定到assemble任务(模块构建的最终打包任务),同时优化目标模块的判断逻辑,覆盖两种常见构建场景:

修改后的根build.gradle脚本

subprojects {
    tasks.named('assemble').configure { assembleTask ->
        assembleTask.doLast {
            // 读取配置开关,默认关闭
            def copyEnabled = providers
                    .gradleProperty("liferay.workspace.module.build.copy")
                    .map { it.toBoolean() }
                    .orElse(false)

            if (!copyEnabled) {
                return
            }

            // 读取自定义输出目录,默认在根目录下的versioned-jars
            def outputDirProvider = providers
                    .gradleProperty("liferay.workspace.module.build.copy.location")
                    .orElse("$rootDir/versioned-jars")

            // 判断当前模块是否是本次构建的目标模块
            boolean isTargetModule = false

            // 场景1:在模块目录下直接执行构建命令(如gradle assemble/build)
            if (project.projectDir.canonicalPath == gradle.startParameter.currentDir.canonicalPath) {
                isTargetModule = true
            }
            // 场景2:在根目录执行指定模块的构建命令(如gradle :my-module:assemble)
            else {
                def currentProjectPath = project.path
                isTargetModule = gradle.startParameter.taskNames.any { taskName ->
                    taskName.startsWith(currentProjectPath)
                }
            }

            if (isTargetModule) {
                println "> Build Copy :: Copying JAR for ${project.path}"
                def outputDir = file(outputDirProvider)
                outputDir.mkdirs()

                // 复制最终生成的JAR包(和build/libs中的版本完全一致)
                copy {
                    from project.tasks.jar.archiveFile
                    into outputDir
                }

                println "> Build Copy :: JAR Successfully Copied at ${outputDir}"
            }
        }
    }
}

关键优化点

  • 绑定到assemble任务:assemble是Liferay模块构建的最终打包任务,所有对JAR的后续处理完成后才会执行doLast,确保复制的是最终产物。
  • 精准判断目标模块:覆盖两种常见构建场景,避免原逻辑中contains方法可能导致的误判(比如子模块路径包含父模块路径的情况)。
  • 保持配置灵活性:依然通过gradle.properties控制开关和输出目录,无需修改脚本即可调整行为。

配置方式

在gradle.properties中添加以下配置(按需调整):

# 开启JAR复制功能
liferay.workspace.module.build.copy=true
# 自定义输出目录(可选,默认是根目录下的versioned-jars)
liferay.workspace.module.build.copy.location=/opt/deploy-jars

使用说明

执行构建命令时,确保包含assemble阶段:

  • 在模块目录执行:gradle build 或 gradle assemble
  • 在根目录执行指定模块:gradle :your-module-name:build 或 gradle :your-module-name:assemble

内容的提问来源于stack exchange,提问作者Anubhav Kalra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 17:37:27