eastwater
eastwater

Reputation: 5560

gradle project build directory does not exist

Trying to create a properties file (foo.properties) and add it to the root of a war.

apply plugin: 'war'

task createProperties {
    FileOutputStream os = new FileOutputStream("${project.buildDir}/foo.properties");
    ...
}

war {
     dependsOn createProperties
     from "${project.buildDir}/foo.properties"
     ...
}

What went wrong:

A problem occurred evaluating project ':app'.
> E:\app\build\build.properties (The system cannot find the path specified)

Do I need to create the build dir?

for war, is there an output dir for webapp? (sourceSet: src/main/webapp) It is better to create the foo.properties directly under the webapp outputDir.

Upvotes: 0

Views: 8386

Answers (2)

ToYonos
ToYonos

Reputation: 16833

Try like this :

task createProperties {
    doFirst {
        FileOutputStream os = new FileOutputStream("${project.buildDir}/foo.properties");
        ...
    }
}

Explanation with an example :

task foo {
    println 'foo init line'
    doFirst {
        println 'foo doFirst'
    } 
    doLast {
        println 'foo doLast'
    }
}

task bar {
    println 'bar init line'
    doFirst {
        println 'bar doFirst'
    } 
    doLast {
        println 'bar doLast'
    }
}

Now for the commande gradle clean bar, you'll get as otput :

foo init line
bar init line
:clean
:foo
foo doFirst
foo doLast
:bar
bar doFirst
bar doLast

The clean step went after the init step hence in your case, the foo.properties is erased before trying to be found.

Upvotes: 0

Vampire
Vampire

Reputation: 38639

You should do

 war {
      from createProperties
      ...
 }

this will add an implicit dependency on the createProperties task automatically, so no need for a dependsOn.

For this to work you need to specify the output of your createProperties cleanly like

task createProperties {
    outputs.file("$buildDir/foo.properties")
    doLast {
        FileOutputStream os = new FileOutputStream("$buildDir/foo.properties");
        ...
    }
}

But actually you should use a task of type WriteProperties, that looks cleaner and is better for reproducible builds. Something like this:

task createProperties(type: WriteProperties) {
    outputFile "$buildDir/foo.properties"
    property 'foo', 'bar'
}

If your properties are calculated dynamically and not statically (which I assume, otherwise you could simply create the file manually) you should also set the dynamic parts as inputs of the task, so that the tasks up-to-date checks work properly and the task is only run when necessary because some input changed.

Upvotes: 2

Related Questions