Kri*_*nom 3 java groovy gradle
我正在尝试将命令的输出放入某个文件。在写入文件之前,我想删除文件而不是进行写入操作。这是我的gradle脚本
group 'org.example'
version '1.0-SNAPSHOT'
task deletefiles(type: Delete){
delete "$projectDir/somefile.txt"
}
task writefile(type: Exec, dependsOn: deletefiles){
commandLine 'echo', "Hello World"
standardOutput = new FileOutputStream("$projectDir/somefile.txt")
}
Run Code Online (Sandbox Code Playgroud)
但是当我运行 writefile 任务时,出现以下错误
Execution failed for task ':deletefiles'.
> java.io.IOException: Unable to delete file 'D:\workspace\code\repo\sample-gradle-mono\somefile.txt'
Run Code Online (Sandbox Code Playgroud)
知道出了什么问题吗?
我猜的一件事是 gradle 在deletefiles任务可以开始之前以某种方式获取文件锁定。如果是这样,我们如何才能实现这一目标?
编辑 1:环境信息 -
------------------------------------------------------------
Gradle 6.3
------------------------------------------------------------
Build time: 2020-03-24 19:52:07 UTC
Revision: bacd40b727b0130eeac8855ae3f9fd9a0b207c60
Kotlin: 1.3.70
Groovy: 2.5.10
Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM: 11.0.4 (Oracle Corporation 11.0.4+11)
OS: Windows 10 10.0 amd64
Run Code Online (Sandbox Code Playgroud)
在项目配置阶段在您的 gradle 中执行以下行的问题
standardOutput = new FileOutputStream("$projectDir/somefile.txt")
Run Code Online (Sandbox Code Playgroud)
这意味着即使在启动任何 gradle 任务之前,流已被创建并被锁定。
尝试这个 groovy 配置以查看问题:
class MyStream extends FileOutputStream{
MyStream(String f){
super(f)
println "write $f stream created"
}
}
task deletefiles(type: Delete){
println "delete init"
doFirst{
println "delete doFirst" //triggered just before deletion
}
delete "out.txt"
}
task writefile(type: Exec, dependsOn: deletefiles){
println "write init"
commandLine 'cmd', '/C', 'echo', "Hello World"
standardOutput = new MyStream("out.txt")
}
Run Code Online (Sandbox Code Playgroud)
在输出中,您可以看到在任务执行之前创建了流:
cmd> gradle writeFile
> Configure project :
delete init
write init
write out.txt stream created
> Task :deletefiles FAILED
delete doFirst
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':deletefiles'.
> java.io.IOException: Unable to delete file 'out.txt'
Run Code Online (Sandbox Code Playgroud)
要修复它-standardOutput
在执行“Exec”任务之前定义:
class MyStream extends FileOutputStream{
MyStream(String f){
super(f)
println "write $f stream created"
}
}
task deletefiles(type: Delete){
println "delete init"
doFirst{
println "delete doFirst"
}
delete "out.txt"
}
task writefile(type: Exec, dependsOn: deletefiles){
println "write init"
commandLine 'cmd', '/C', 'echo', "Hello World"
doFirst{
println "write doFirst"
standardOutput = new MyStream("out.txt")
}
doLast{
println "write doLast"
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
cmd>gradle writeFile
> Configure project :
delete init
write init
> Task :deletefiles
delete doFirst
> Task :writefile
write doFirst
write out.txt stream created
write doLast
BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed
Run Code Online (Sandbox Code Playgroud)
增加一些清晰度:
例如这个任务定义
task writefile(type: Exec, dependsOn: deletefiles){
println "write init"
commandLine 'cmd', '/C', 'echo', "Hello World"
doFirst{
println "write doFirst"
standardOutput = new MyStream("out.txt")
}
doLast{
println "write doLast"
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在您的 gradle 中替换为以下 groovy 代码:
def writefile = project.task( [type: Exec, dependsOn: deletefiles], 'writeFile' )
println "write init"
writefile.setCommandLine( ['cmd', '/C', 'echo', "Hello World"] )
writefile.getActions().add( 0, {
//those commands will be executed later when task `writefile` decided to be executed by gradle
println "write doFirst"
writefile.standardOutput = new FileOutputStream("out.txt")
} as Action)
writefile.getActions().add( {
//those commands will be executed later when task `writefile` decided to be executed by gradle
println "write doLast"
} as Action)
Run Code Online (Sandbox Code Playgroud)
可以解释这种行为的官方文档链接:
https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:settings_file
https://docs.gradle.org/current/userguide/more_about_tasks.html
归档时间: |
|
查看次数: |
194 次 |
最近记录: |