Gradle: correctly create dependency on generate source

Answered

I've seen so many examples of how to include generated OpenAPI source but none of them fit my situation.  Here's my build.gradle.kts:

val ktorVersion = "1.6.6"
val exposedVersion = "0.37.3"
val log4jVersion = "2.1"
val junitVersion = "5.8.2"
val kotlinReactWrapperVersion = "17.0.2"
val kotlinReactVersion = "1.5.30"

plugins {
     kotlin("multiplatform") version "1.7.20-RC"
     kotlin("plugin.serialization") version "1.7.20-RC"
     id("com.github.johnrengelman.shadow") version "7.0.0"
     id("org.openapi.generator") version "7.4.0"
     application
     // kotlin("jvm")
}

openApiGenerate {
     // https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-gradle-plugin
     generatorName.set("kotlin")
     inputSpec.set("$rootDir/openapi/profileGet.yaml")
     outputDir.set("$rootDir/src/openAPIStubs")
     packageName.set("au.com.miit.stubs.model")
     // Your other specification
}

group = "au.com.miit"
version = "1.0"

repositories {
     mavenCentral()
     maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
     maven {
         url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
         name = "ktor-eap"
     }
}

kotlin {
     jvm {
         compilations.all {
             kotlinOptions.jvmTarget = "1.8"
         }
         withJava()
         testRuns["test"].executionTask.configure {
             useJUnitPlatform()
         }
     }
     js(IR) {
         binaries.executable()
         browser {
             commonWebpackConfig {
                 cssSupport.enabled = true
             }
         }
     }
     sourceSets {
         val commonMain by getting
         val commonTest by getting {
             dependencies {
                 implementation(kotlin("test"))
             }
         }
         val jvmMain by getting {
             dependencies {
                 implementation("io.ktor:ktor-server-netty:$ktorVersion")
                 implementation("io.ktor:ktor-html-builder:$ktorVersion")
                 implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.2")
                 implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
                 implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
                 implementation("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
                 implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
                 implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
                 implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
                 implementation("org.jetbrains.exposed:exposed-kotlin-datetime:$exposedVersion")
                 implementation("com.google.firebase:firebase-admin:7.2.0")
                 implementation("mysql:mysql-connector-java:8.0.19")
                 implementation("com.google.code.gson:gson:2.9.0")
                 implementation("org.postgresql:postgresql:42.6.0")
             }
         }
         val jvmTest by getting
         val jsMain by getting {
             dependencies {
                 implementation("org.jetbrains.kotlin-wrappers:kotlin-react:$kotlinReactWrapperVersion-pre.240-kotlin-$kotlinReactVersion")
                 implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:$kotlinReactWrapperVersion-pre.240-kotlin-$kotlinReactVersion")
             }
         }
         val jsTest by getting
     }
     jvmToolchain(21)
}

application {
     mainClass.set("au.com.miit.application.ServerKt")
     sourceSets {
         main {
             java {
                 srcDir("$rootDir/src/openAPIStubs/src/main/kotlin")
                 dependencies {
                     implementation("com.squareup.moshi:moshi:1.8.0")
                     implementation("com.squareup.okhttp3:okhttp:4.2.0")
                 }
             }
         }
     }
}

tasks.named<Copy>("jvmProcessResources") {
     val jsBrowserDistribution = tasks.named("jsBrowserDistribution")
     from(jsBrowserDistribution)
}

tasks.named<JavaExec>("run") {
     dependsOn(tasks.named<Jar>("jvmJar"))
     systemProperty("DB.server", "192.168.1.10")
     systemProperty("http.port", "8080")
     classpath(tasks.named<Jar>("jvmJar"))
}

tasks.shadowJar {
     manifest {
         attributes(Pair("Main-Class", "au.com.miit.application.ServerKt"))
     }
     dependsOn(tasks.openApiGenerate)
}

dependencies {
     implementation(kotlin("stdlib-jdk8"))
}

and ./gradlew shadowJar outputs:

...
A problem was found with the configuration of task ':openApiGenerate' (type 'GenerateTask').
 - Gradle detected a problem with the following location: '/home/mounty/Miit/Miit2/src/openAPIStubs'.
   
   Reason: Task ':compileKotlinJvm' uses this output of task ':openApiGenerate' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
   
   Possible solutions:
     1. Declare task ':openApiGenerate' as an input of ':compileKotlinJvm'.
     2. Declare an explicit dependency on ':openApiGenerate' from ':compileKotlinJvm' using Task#dependsOn.
     3. Declare an explicit dependency on ':openApiGenerate' from ':compileKotlinJvm' using Task#mustRunAfter.

How do I fix this?  as in:  what line or lines do I add to build.gradle.kts correctly to fix the reported problem?

0
4 comments

Well, as the error suggests, you have the following options:

1. Declare task ':openApiGenerate' as an input of ‘:compileKotlinJvm

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {

    inputs.dir("${projectDir}/src/openAPIStubs")   // add this line
}

2. Declare an explicit dependency on ':openApiGenerate' from ':compileKotlinJvm' using Task#dependsOn

tasks.all {
    task -> 
        if(task.name == "compileKotlinJvm"){
            dependsOn ':openApiGenerate'
        }
}

3. Declare an explicit dependency on ':openApiGenerate' from ':compileKotlinJvm' using Task#mustRunAfter

tasks.named("compileKotlinJvm") {
    mustRunAfter(":openApiGenerate")
}
0

Thanks;  I don't know the `build.gradle.kts` syntax completely.  What about:

tasks.named("compileKotlinJvm") {
    dependsOn(":openApiGenerate")
}

because `mustRunAfter` doesn't actually make `:openApiGenerate` a target whose dependencies must be checked, as far as I can tell.

0

All of those are, technically, viable options, you can decide which one works best for you and your Project, as you are familiar with its' structure and its' intended workflows.

0

Thanks Roman;  I appreciate your help.

0

Please sign in to leave a comment.