【问题标题】:gradle - copy file after its generationgradle - 生成后复制文件
【发布时间】:2015-06-04 06:51:09
【问题描述】:


我尝试构建 jar,然后将其复制到另一个文件夹。

task createJar(type: Jar) {
    archiveName = "GradleJarProject.jar"
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
            'Implementation-Version': version,
            'Main-Class': 'me.test.Test'
    }
    baseName = project.name
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar

}

task copyJarToBin {
    copy {
        from 'build/libs/GradleJarProject.jar'
        into "d:/tmp"
    }
}

task buildApp (dependsOn: [clean, createJar, copyJarToBin])

但我想不出一个问题。 copyJarToBin 任务尝试复制旧 jar。如果我删除项目中的 /build 文件夹并运行 buildApp() 任务,任务 createJar() 将生成 .jar 文件,但 copyJarToBin() 不会找到该 .jar 文件。

你能帮帮我吗?
谢谢。

【问题讨论】:

    标签: java gradle


    【解决方案1】:

    罪魁祸首是你的copyJarToBin 任务。做的时候

    task copyJarToBin {
        copy {
            from 'build/libs/GradleJarProject.jar'
            into "d:/tmp"
        }
    }
    

    您在配置期间使用copy 方法复制jar。 (请参阅https://docs.gradle.org/current/userguide/userguide_single.html#sec:build_phases 的 gradle 用户指南以了解构建生命周期) 您想在执行阶段(任务的执行)运行实际的复制操作。

    解决这个问题的一种方法是将 copy 方法的调用移到 doLast 块中:

    task copyJarToBin {
        doLast {
            copy {
                from 'build/libs/GradleJarProject.jar'
                into "d:/tmp"
            }
    
        }
    }
    

    这种方法的问题在于,即使文件没有更改,您也不会受益于 gradles 增量构建功能并在每次执行任务时都复制该文件。

    编写 copyJarToBin 任务的更好、更惯用的方法是将任务实现更改为使用 Copy 任务类型:

    task copyJarToBin(type: Copy) {
        from 'build/libs/GradleJarProject.jar'
        into "d:/tmp"
    }   
    

    我们甚至可以利用 gradle 的自动装配功能来改进这个 sn-p。您可以将一个任务的输出声明为另一个任务的输入。因此,您可以简单地执行以下操作,而不是编写 `build/libs/GradleJarProject.jar':

    task copyJarToBin(type: Copy) {
        from createJar // shortcut for createJar.outputs.files
        into "d:/tmp"
    }   
    

    现在您无需担心任务排序,因为 gradle 知道必须先执行 createJar 任务,然后才能执行 copyJarToBin 任务。

    【讨论】:

    • 非常感谢您的帮助。
    【解决方案2】:

    我认为上述答案有些陈旧。这是使用 gradle 3.3 的答案

    jar {
        baseName = 'my-app-name'
        version =  '0.0.1'
    }
    
    task copyJar(type: Copy) {
        from jar // here it automatically reads jar file produced from jar task
        into 'destination-folder'
    }
    
    build.dependsOn copyJar
    

    【讨论】:

    • 有没有办法在构建 jar 后更新它?我尝试使用 jar -uf ... 命令将生成的文件附加到 jar 中,但这必须发生在 jar 生成之后。
    【解决方案3】:

    刚刚对上述答案做了一些更正:

    jar {
        baseName = "$artifactId"
        version =  '0.0.1'
    }
    
    task copyJar(type: Copy) {
        from jar // copies output of file produced from jar task
        into 'destination-folder'
    }
    
    build.finalizedBy copyJar
    

    【讨论】:

    • 这是否适用于所有已创建 jar 的多项目构建? (我在 gradle 6.5.1)
    • 它应该可以工作。您需要将这段代码放入所有单独的 Gradle 构建文件中。
    【解决方案4】:

    您可能需要确保它们以正确的顺序运行,

    task copyJarToBin(type:Copy,dependsOn:[createJar]) {
       copy {
         from "${buildDir}/GradleJarProject.jar"  // needs to be gstring       
         into "d:/tmp"
        }
    }
    

    【讨论】:

    • 使用Copy任务是正确的方向,但需要去掉copy方法,以免在执行阶段执行复制操作
    • @Theresa Forster 你是对的。在 createJar() 之前调用了 copyJarToBin()。我将使用 mustRunAfter 函数。谢谢。
    【解决方案5】:

    在我的用例中,我需要 projectA 从 projectB 的 jar 输出中使用(解压缩)内容。在这种情况下,需要嵌入的 doLast { copy { .. }}

    configurations {
        consumeJarContents
    }
    dependencies {
        consumeJarContents project(':projectB')
    }
    
    task copyFromJar() {
        dependsOn configurations.consumeJarContents
        doLast {
            copy {
                configurations.consumeJarContents.asFileTree.each {
                    from( zipTree(it) )
                }
                into "$buildDir/files"
            }
        }
    }
    

    task copyFromJar(type: Copy) 在这种情况下的问题是复制配置阶段检查 jar 文件,因为它尚未创建,所以它没有找到它,因此在执行时为任务声明 NO-INPUT。

    【讨论】:

      猜你喜欢
      • 2020-07-26
      • 2016-04-01
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 2019-10-13
      • 2015-05-27
      相关资源
      最近更新 更多