build.gradle.kts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
  2. import com.github.jk1.license.filter.LicenseBundleNormalizer
  3. import com.github.jk1.license.render.InventoryMarkdownReportRenderer
  4. plugins {
  5. id("com.github.jk1.dependency-license-report")
  6. id("otel.java-conventions")
  7. id("otel.publish-conventions")
  8. id("io.opentelemetry.instrumentation.javaagent-shadowing")
  9. }
  10. description = "OpenTelemetry Javaagent"
  11. group = "io.opentelemetry.javaagent"
  12. // this configuration collects libs that will be placed in the bootstrap classloader
  13. val bootstrapLibs by configurations.creating {
  14. isCanBeResolved = true
  15. isCanBeConsumed = false
  16. }
  17. // this configuration collects libs that will be placed in the agent classloader, isolated from the instrumented application code
  18. val javaagentLibs by configurations.creating {
  19. isCanBeResolved = true
  20. isCanBeConsumed = false
  21. }
  22. // this configuration collects just exporter libs (also placed in the agent classloader & isolated from the instrumented application)
  23. val exporterLibs by configurations.creating {
  24. isCanBeResolved = true
  25. isCanBeConsumed = false
  26. }
  27. // exclude dependencies that are to be placed in bootstrap from agent libs - they won't be added to inst/
  28. listOf(javaagentLibs, exporterLibs).forEach {
  29. it.run {
  30. exclude("org.slf4j")
  31. exclude("io.opentelemetry", "opentelemetry-api")
  32. exclude("io.opentelemetry", "opentelemetry-api-metrics")
  33. exclude("io.opentelemetry", "opentelemetry-semconv")
  34. }
  35. }
  36. val licenseReportDependencies by configurations.creating {
  37. extendsFrom(bootstrapLibs)
  38. }
  39. dependencies {
  40. bootstrapLibs(project(":instrumentation-api"))
  41. bootstrapLibs(project(":instrumentation-api-annotation-support"))
  42. bootstrapLibs(project(":javaagent-bootstrap"))
  43. bootstrapLibs(project(":javaagent-instrumentation-api"))
  44. bootstrapLibs("org.slf4j:slf4j-simple")
  45. javaagentLibs(project(":javaagent-extension-api"))
  46. javaagentLibs(project(":javaagent-tooling"))
  47. javaagentLibs(project(":muzzle"))
  48. exporterLibs(project(":javaagent-exporters"))
  49. // We only have compileOnly dependencies on these to make sure they don't leak into POMs.
  50. licenseReportDependencies("com.github.ben-manes.caffeine:caffeine") {
  51. isTransitive = false
  52. }
  53. licenseReportDependencies("com.blogspot.mydailyjava:weak-lock-free")
  54. // TODO ideally this would be :instrumentation instead of :javaagent-tooling
  55. // in case there are dependencies (accidentally) pulled in by instrumentation modules
  56. // but I couldn"t get that to work
  57. licenseReportDependencies(project(":javaagent-tooling"))
  58. licenseReportDependencies(project(":javaagent-extension-api"))
  59. testCompileOnly(project(":javaagent-bootstrap"))
  60. testCompileOnly(project(":javaagent-instrumentation-api"))
  61. testImplementation("com.google.guava:guava")
  62. testImplementation("io.opentracing.contrib.dropwizard:dropwizard-opentracing:0.2.2")
  63. }
  64. val javaagentDependencies = dependencies
  65. // collect all bootstrap and javaagent instrumentation dependencies
  66. project(":instrumentation").subprojects {
  67. val subProj = this
  68. plugins.withId("otel.javaagent-bootstrap") {
  69. javaagentDependencies.run {
  70. add(bootstrapLibs.name, project(subProj.path))
  71. }
  72. }
  73. plugins.withId("otel.javaagent-instrumentation") {
  74. javaagentDependencies.run {
  75. add(javaagentLibs.name, project(subProj.path))
  76. }
  77. }
  78. }
  79. tasks {
  80. processResources {
  81. from(rootProject.file("licenses")) {
  82. into("META-INF/licenses")
  83. }
  84. }
  85. // lightShadow is the default classifier we publish so disable the default jar.
  86. jar {
  87. enabled = false
  88. }
  89. val relocateJavaagentLibs by registering(ShadowJar::class) {
  90. configurations = listOf(javaagentLibs)
  91. duplicatesStrategy = DuplicatesStrategy.FAIL
  92. archiveFileName.set("javaagentLibs-relocated.jar")
  93. // exclude bootstrap projects from javaagent libs - they won't be added to inst/
  94. dependencies {
  95. exclude(project(":instrumentation-api"))
  96. exclude(project(":instrumentation-api-annotation-support"))
  97. exclude(project(":javaagent-bootstrap"))
  98. exclude(project(":javaagent-instrumentation-api"))
  99. }
  100. }
  101. val relocateExporterLibs by registering(ShadowJar::class) {
  102. configurations = listOf(exporterLibs)
  103. archiveFileName.set("exporterLibs-relocated.jar")
  104. }
  105. //Includes instrumentations, but not exporters
  106. val lightShadow by registering(ShadowJar::class) {
  107. configurations = listOf(bootstrapLibs)
  108. dependsOn(relocateJavaagentLibs)
  109. isolateClasses(relocateJavaagentLibs.get().outputs.files)
  110. archiveClassifier.set("")
  111. manifest {
  112. attributes(
  113. "Main-Class" to "io.opentelemetry.javaagent.OpenTelemetryAgent",
  114. "Agent-Class" to "io.opentelemetry.javaagent.OpenTelemetryAgent",
  115. "Premain-Class" to "io.opentelemetry.javaagent.OpenTelemetryAgent",
  116. "Can-Redefine-Classes" to true,
  117. "Can-Retransform-Classes" to true
  118. )
  119. }
  120. }
  121. //Includes everything needed for OOTB experience
  122. val shadowJar by existing(ShadowJar::class) {
  123. configurations = listOf(bootstrapLibs)
  124. dependsOn(relocateJavaagentLibs, relocateExporterLibs)
  125. isolateClasses(relocateJavaagentLibs.get().outputs.files)
  126. isolateClasses(relocateExporterLibs.get().outputs.files)
  127. duplicatesStrategy = DuplicatesStrategy.EXCLUDE
  128. archiveClassifier.set("all")
  129. manifest {
  130. attributes(lightShadow.get().manifest.attributes)
  131. }
  132. }
  133. assemble {
  134. dependsOn(lightShadow, shadowJar)
  135. }
  136. withType<Test>().configureEach {
  137. dependsOn(shadowJar)
  138. inputs.file(shadowJar.get().archiveFile)
  139. jvmArgs("-Dotel.javaagent.debug=true")
  140. doFirst {
  141. // Defining here to allow jacoco to be first on the command line.
  142. jvmArgs("-javaagent:${shadowJar.get().archiveFile.get().asFile}")
  143. }
  144. testLogging {
  145. events("started")
  146. }
  147. }
  148. val cleanLicenses by registering(Delete::class) {
  149. delete(rootProject.file("licenses"))
  150. }
  151. named("generateLicenseReport").configure {
  152. dependsOn(cleanLicenses)
  153. }
  154. publishing {
  155. publications {
  156. named<MavenPublication>("maven") {
  157. artifact(lightShadow)
  158. }
  159. }
  160. }
  161. }
  162. licenseReport {
  163. outputDir = rootProject.file("licenses").absolutePath
  164. renderers = arrayOf(InventoryMarkdownReportRenderer())
  165. configurations = arrayOf(licenseReportDependencies.name)
  166. excludeGroups = arrayOf(
  167. "io.opentelemetry.instrumentation",
  168. "io.opentelemetry.javaagent"
  169. )
  170. filters = arrayOf(LicenseBundleNormalizer("$projectDir/license-normalizer-bundle.json", true))
  171. }
  172. fun CopySpec.isolateClasses(jars: Iterable<File>) {
  173. jars.forEach {
  174. from(zipTree(it)) {
  175. // important to keep prefix "inst" short, as it is prefixed to lots of strings in runtime mem
  176. into("inst")
  177. rename("(^.*)\\.class\$", "\$1.classdata")
  178. // Rename LICENSE file since it clashes with license dir on non-case sensitive FSs (i.e. Mac)
  179. rename("""^LICENSE$""", "LICENSE.renamed")
  180. }
  181. }
  182. }