Repository: open-telemetry/opentelemetry-java
File: all/build.gradle.kts (Kotlin)

Code before:
        }
        subproject.tasks.withType<Jar>().forEach {
          if (it.archiveClassifier.get().isEmpty() && !it.archiveFile.get().toString().contains("jmh")) {
            jarTasks.add(it)
          }
        }
      }
    }
  }

  testImplementation("com.tngtech.archunit:archunit-junit5")
}

val artifactsAndJarsFile = layout.buildDirectory.file("artifacts_and_jars.txt").get().asFile

var writeArtifactsAndJars = tasks.register("writeArtifactsAndJars") {

  dependsOn(jarTasks)
  artifactsAndJarsFile.parentFile.mkdirs()
  artifactsAndJarsFile.createNewFile()
  val content = jarTasks.stream()
    .map {
      it.archiveBaseName.get() + ":" + it.archiveFile.get().toString()
    }.collect(Collectors.joining("\n"))
  artifactsAndJarsFile.writeText(content)
}

tasks {
  // We don't compile much here, just some API boundary tests. This project is mostly for
  // aggregating jacoco reports and it doesn't work if this isn't at least as high as the
  // highest supported Java version in any of our projects. All of our
  // projects target Java 8 except :exporters:http-sender:jdk, which targets
  // Java 11
  withType(JavaCompile::class) {
    options.release.set(11)
  }

  val testJavaVersion: String? by project
  test {
    enabled = testJavaVersion != "8"
    dependsOn(writeArtifactsAndJars)
    environment("ARTIFACTS_AND_JARS", artifactsAndJarsFile.absolutePath)
  }
}

// https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage.html

val sourcesPath by configurations.creating {
  isCanBeResolved = true
  isCanBeConsumed = false
  extendsFrom(configurations.implementation.get())

Review comment (performance):
this is what AI is saying and suggesting for me (and I've found it's a lot better at Gradle than me 😄)

> The body of tasks.register {} is a *configuration* action, not an execution action. All of mkdirs(), createNewFile(), writeText() run at **configuration time** for every Gradle invocation, not when the task is actually executed. This should be wrapped in a doLast {} block to defer the side effects to execution time. As-is, the file is written even when the task is up-to-date or not requested.
>
> The task does not declare inputs/outputs, so Gradle cannot perform up-to-date checking. Consider adding outputs.file(artifactsAndJarsFile) and inputs from jarTasks so that it is properly cached and only re-runs when jar outputs change.

```suggestion
val writeArtifactsAndJars = tasks.register("writeArtifactsAndJars") {
  dependsOn(jarTasks)
  outputs.file(artifactsAndJarsFile)
  doLast {
    artifactsAndJarsFile.parentFile.mkdirs()
    val content = jarTasks.stream()
      .map {
        it.archiveBaseName.get() + ":" + it.archiveFile.get().toString()
      }.collect(Collectors.joining("\n"))
    artifactsAndJarsFile.writeText(content)
  }
}
```

Code after:
          if (it.archiveClassifier.get().isEmpty() && !it.name.contains("jmh")) {
            jarTasks.add(it)
          }
        }
      }
    }
  }

  testImplementation("com.tngtech.archunit:archunit-junit5")
}

// Custom task type for writing artifacts and jars - configuration cache compatible
abstract class WriteArtifactsAndJars : DefaultTask() {
  @get:Input
  abstract val artifactData: MapProperty<String, String>

  @get:OutputFile
  abstract val outputFile: RegularFileProperty

  @TaskAction
  fun writeFile() {
    val file = outputFile.get().asFile
    file.parentFile.mkdirs()
    val content = artifactData.get().entries.joinToString("\n") { (baseName, filePath) ->
      "$baseName:$filePath"
    }
    file.writeText(content)
  }
}

val artifactsAndJarsFile = layout.buildDirectory.file("artifacts_and_jars.txt")

val writeArtifactsAndJars = tasks.register<WriteArtifactsAndJars>("writeArtifactsAndJars") {
  // Set up task dependencies
  dependsOn(jarTasks)

  // Configure the task inputs and outputs using providers
  artifactData.set(provider {
    jarTasks.associate { jar ->
      jar.archiveBaseName.get() to jar.archiveFile.get().asFile.absolutePath
    }
  })
  outputFile.set(artifactsAndJarsFile)
}

tasks {
  // This module depends on all published subprojects (for JaCoCo coverage aggregation and
  // arch tests). Since :exporters:http-sender:jdk targets Java 11, the compiler needs
  // release 11 to resolve its classes on the classpath.
  withType(JavaCompile::class) {
    options.release.set(11)