Problem with compileJava dependsOn another task


(Sverre Moe) #1

I have a protobuf task that generates the Java classes. This must be run before compileJava.
The protobuf task has a doFirst that creates the src/main/java directory and creates a module-info.java under there.

The protobuf task is executed before compileJava, but the compileJava doesn’t work and complain about module not found. With debug I have seen that protobuf-java is put on the module path along with the generated java classes.

Running the build for a second time works.
Also working if running ‘gradle protobuf’ then ‘gradle build’ separately.

> Task :protobuf
Task ':protobuf' is not up-to-date because:
  Task has not declared any outputs despite executing actions.
Starting process 'command 'protoc''. Working directory: /home/sverre/workspace/protobuf-library Command: protoc --proto_path=. --proto_path=/usr/include --java_out=src/main/java -I/home/sverre/workspace/protobuf-library/system/protobuf /home/sverre/workspace/protobuf-library/system/protobuf/client.proto
Successfully started process 'command 'protoc''
:protobuf (Thread[Task worker for ':',5,main]) completed. Took 0.155 secs.
:compileJava (Thread[Task worker for ':',5,main]) started.

> Task :compileJava FAILED
Task ':compileJava' is not up-to-date because:
  Task has failed previously.
All input files are considered out-of-date for incremental task ':compileJava'.
Full recompilation is required because no incremental change information is available. This is usually caused by clean builds or changing compiler arguments.
Compiling with JDK Java compiler API.
/home/sverre/workspace/protobuf-library/src/main/java/module-info.java:3: error: module not found: protobuf.java
    requires protobuf.java;

gradle.build
task protobufJava(type: Exec) {
    final def javaDir = "src/main/java"
    final def javaFile = "module-info.java"
    final def protoDir = "${projectDir}/system/proto"
    final def protoPaths = fileTree(dir: protoDir, include: '**/*.proto')
    final def protoFiles = protoPaths.each { it }.join(' ')

    final def javaFileContent = """
module com.company.proto {
    requires protobuf.java;
}
"""

    doFirst {
        mkdir javaDir
        new File("${javaDir}/${javaFile}").text = javaFileContent
    }

    commandLine "protoc --proto_path=. --proto_path=/usr/include --java_out=${javaDir} -I${protoDir} ${protoFiles}".split(' ')
}

compileJava.dependsOn protobufJava

Any idea how I can get protobufJava to finish before compileJava starts?

According to the compileJava output it seems it has all the java files and module-info, also the protobuf-java dependency. So I am not sure what it is complaining about.

Edit: Just tried with the latest Gradle 5.0. Still an issue.

Edit: The problem seems to be the doFirst writing the file module-info.java
If I create the directory and file prior to gradle build, it works fine.
I have checked after that the file is there, and it has the correct content.

During the configure stage, if the file exist it outputs
Found module name ‘com.company.protobuf’
Does that mean the module-info.java, needs to be there prior to configure?
Edit: Even if I move the file write to ext block, which runs under the configure phase, it still fails.


(Sverre Moe) #2

I found a solution that works, but it does not seem very elegant.

id 'org.javamodularity.moduleplugin' version '1.2.1' apply false

ext {
    javaDir = "src/main/java"
    writeModuleInfo()
}

apply plugin: 'org.javamodularity.moduleplugin'

void writeModuleInfo() {
    final def javaFile = "module-info.java"
    final def javaFileContent = """
module com.company.proto {
    requires protobuf.java;
}
"""
    mkdir javaDir
    new File("${javaDir}/${javaFile}").text = javaFileContent
}