javagradlebuild.gradlegradle-task

Gradle continuous build behaves odd


Gradle is a magic box for me. I often don't get it and always do try and error. I use gradle 8.1 and groovy scripts. I have this small task

import java.time.Instant

tasks.register('continuous-build') {
    dependsOn tasks.compileJava
    onlyIf { !compileJava.state.upToDate }
    logger.lifecycle("Job executed at " + Instant.now())
    doLast {
        def file = new File(projectDir, "build/classes/java/main/.reloadTrigger");
        file.createNewFile();
        file.setLastModified(Instant.now().toEpochMilli())
        logger.lifecycle("This message is never seen")
    }
}

I want this task to run with --continuous-build and just touch a file if it's done compiling.

this is what I do:

Run ./gradlew continuous-build --continuous

$ ./gradlew continuous-build --continuous
Reload triggered at 2023-11-10T11:48:50.446501720Z   
BUILD SUCCESSFUL in 1s
6 actionable tasks: 1 executed, 5 up-to-date
Waiting for changes to input files... (ctrl-d to exit)

Make a small change to Main.java which compiles fine

modified: [...]Main.java
Change detected, executing build...
Reload triggered at 2023-11-10T11:49:02.870526619Z
BUILD SUCCESSFUL in 1s
6 actionable tasks: 1 executed, 2 from cache, 3 up-to-date
Waiting for changes to input files... (ctrl-d to exit)

After this the file timestamp is changed. That is what I want.

Make a small change to Main.java which compiles with error

modified: [...]Main.java
Change detected, executing build...   
Reload triggered at 2023-11-10T11:49:09.303034432Z    
> Task :compileJava FAILED
[...]Main.java:22: error: <identifier> expected
    publi static final String ANSWER = "42";
         ^
1 error
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.   
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.    
* Get more help at https://help.gradle.org    
BUILD FAILED in 1s
3 actionable tasks: 2 executed, 1 up-to-date    
Waiting for changes to input files... (ctrl-d to exit)

After this the file timestamp is NOT changed. That is what I want as it compiled with an error.

Make a small change to Main.java which compiles fine again

modified: [...]Main.java
Change detected, executing build...
Reload triggered at 2023-11-10T11:49:14.192599979Z
BUILD SUCCESSFUL in 1s
6 actionable tasks: 1 executed, 5 up-to-date
Waiting for changes to input files... (ctrl-d to exit)

After this the file timestamp is NOT changed anymore even the compilation succeeded. How can I achieve a file touch cmd if compileJava was successful.

And why is the second logging message never seen?

PS I have shortened the output a little bit to make it more readable


Solution

  • Few points to mention:

    So, your doLast action depends on these two lines dependsOn tasks.compileJava and onlyIf { !compileJava.state.upToDate } completely.

    To demonstrate, I have updated your gradle task a little bit to explain.

    import java.time.Instant
    
    tasks.register('continuous-build') {
        dependsOn tasks.compileJava
        onlyIf { !compileJava.state.upToDate }
        logger.lifecycle("Job executed at " + Instant.now())
        doLast {
            def file = new File(projectDir, "build/classes/java/main/.reloadTrigger");
            def created = file.createNewFile();
            logger.lifecycle("File created status :" + created);
            file.setLastModified(Instant.now().toEpochMilli())
            logger.lifecycle("Last modified timestamp of the file: " + file.lastModified());
            logger.lifecycle("This message is never seen")
        }
    } 
    

    First time Execution:

    enter image description here

    enter image description here

    Second time Execution (with no change in Java classes):

    doLast task action will not be executed as explained in the point (because of this line onlyIf { !compileJava.state.upToDate }).

    enter image description here

    Third Time Execution (with the modification in a Java class):

    The doLast task action will be executed and this will trigger the file to be updated instead of creation although the timestamp will be changed this time.

    enter image description here

    Fourth Time Execution (with the modification in a Java class with an error):

    The doLast task action will not be executed due to the compilation error in one of the Java classes detected by the compileJava task and the continuous-build task depends on compileJava.

    enter image description here

    Fifth time Execution (with no error, i.e, reverted the changes): In this case, the third time execution scenario is repeated again.

    enter image description here