@@ -17,17 +17,128 @@ dependencies {
1717
1818base.archivesBaseName = " hypertrace-agent"
1919
20- tasks {
21- processResources {
22- val customizationShadowTask = project(" :instrumentation" ).tasks.named<Jar >(" shadowJar" )
23- val providerArchive = customizationShadowTask.get().archiveFile
24- from(zipTree(providerArchive)) {
25- into(" inst" )
26- rename(" (^.*)\\ .class$" , " $1.classdata" )
20+ // Step 1: Extract instrumentation project's shadowJar into inst/ folder
21+ tasks.register<Copy >(" extractCustomInstrumentationToInst" ) {
22+ description = " Extracts instrumentation project's shadowJar into inst/ folder"
23+
24+ val customizationShadowTask = project(" :instrumentation" ).tasks.named<Jar >(" shadowJar" )
25+ val providerArchive = customizationShadowTask.get().archiveFile
26+
27+ from(zipTree(providerArchive)) {
28+ into(" inst" )
29+ rename(" (^.*)\\ .class$" , " $1.classdata" )
30+ }
31+
32+ into(" $buildDir /resources/main" )
33+
34+ exclude(" **/META-INF/LICENSE" )
35+ dependsOn(customizationShadowTask)
36+ }
37+
38+ // Step 2: Extract OpenTelemetry Java Agent's inst/ files and rename .classdata to .class
39+ tasks.register<Copy >(" extractOtelAgentJarInstClassdata" ) {
40+ description = " Extracts OpenTelemetry Java Agent's .classdata files and renames them to .class"
41+
42+ val otelJavaAgentJar = configurations.compileClasspath.get()
43+ .filter { it.name.contains(" opentelemetry-javaagent" ) }
44+ .singleOrNull() ? : throw GradleException (" OpenTelemetry Java Agent JAR not found" )
45+
46+ doFirst {
47+ println (" OpenTelemetry Java Agent JAR: $otelJavaAgentJar " )
48+ }
49+
50+ from(zipTree(otelJavaAgentJar)) {
51+ include(" inst/**" )
52+ rename(" (^.*)\\ .classdata$" , " $1.class" )
53+ }
54+
55+ // Output to a temporary directory
56+ into(" $buildDir /tmp/otel-classdata-for-relocation" )
57+ }
58+
59+ // Step 3: Move contents to inst/ folder with relocated paths
60+ tasks.register< com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar > (" relocateOtelClassesToInst" ) {
61+ description = " Relocates OpenTelemetry classes to inst/ folder with ai.traceable prefix"
62+
63+ dependsOn(" extractOtelAgentJarInstClassdata" )
64+
65+ from(" $buildDir /tmp/otel-classdata-for-relocation/inst" )
66+
67+ destinationDirectory.set(file(" $buildDir /tmp/relocated-otel-classdata" ))
68+ archiveFileName.set(" relocated-otel-classdata.jar" )
69+
70+ relocate(" io.opentelemetry" , " ai.traceable.io.opentelemetry" )
71+
72+ eachFile {
73+ path = " inst/ai/traceable/$path "
74+ }
75+ }
76+
77+ // Step 3b: Extract the relocated JAR
78+ tasks.register<Copy >(" extractRelocatedOtelClasses" ) {
79+ description = " Extracts relocated OpenTelemetry classes"
80+
81+ dependsOn(" relocateOtelClassesToInst" )
82+
83+ from(zipTree(" $buildDir /tmp/relocated-otel-classdata/relocated-otel-classdata.jar" ))
84+ into(" $buildDir /tmp/relocated-otel-classes" )
85+ }
86+
87+ // task to clean up empty directories
88+ tasks.register(" cleanEmptyDirs" ) {
89+ description = " Removes empty directories from the relocated classes directory"
90+
91+ dependsOn(" extractRelocatedOtelClasses" )
92+
93+ doLast {
94+ // Find and delete empty directories
95+ val instDir = file(" $buildDir /tmp/relocated-otel-classes" )
96+ if (instDir.exists()) {
97+ deleteEmptyDirs(instDir)
2798 }
28- exclude(" **/META-INF/LICENSE" )
29- dependsOn(customizationShadowTask)
3099 }
100+ }
101+
102+ // Helper function to recursively delete empty directories
103+ fun deleteEmptyDirs (dir : File ) {
104+ if (! dir.isDirectory) return
105+
106+ val children = dir.listFiles() ? : return
107+
108+ // Recursively process subdirectories
109+ children.filter { it.isDirectory }.forEach { deleteEmptyDirs(it) }
110+
111+ // Check if directory is empty after processing subdirectories
112+ if (dir.listFiles()?.isEmpty() == true ) {
113+ dir.delete()
114+ }
115+ }
116+
117+ // Step 4: Convert all .class files to .classdata and combine with instrumentation files
118+ tasks.register<Copy >(" combineAndConvertToClassdata" ) {
119+ description = " Combines all classes and converts to .classdata"
120+
121+ dependsOn(" extractCustomInstrumentationToInst" , " cleanEmptyDirs" )
122+
123+ // include the relocated OpenTelemetry classes
124+ from(" $buildDir /tmp/relocated-otel-classes" ) {
125+ rename(" (^.*)\\ .class$" , " $1.classdata" )
126+ }
127+
128+ // Output to the resources directory for inclusion in the final JAR
129+ into(" $buildDir /resources/main" )
130+
131+ // If there are conflicts, our instrumentation project files win
132+ duplicatesStrategy = DuplicatesStrategy .EXCLUDE
133+ }
134+
135+ // Modify the existing processResources task to depend on our new task
136+ tasks.named<ProcessResources >(" processResources" ) {
137+ dependsOn(" combineAndConvertToClassdata" )
138+ exclude(" **/META-INF/LICENSE" )
139+ }
140+
141+ tasks {
31142
32143 shadowJar {
33144 relocate(" com.blogspot.mydailyjava.weaklockfree" , " ai.traceable.io.opentelemetry.instrumentation.api.internal.shaded.weaklockfree" )
@@ -42,18 +153,18 @@ tasks {
42153 relocate(" com.fasterxml.jackson" , " ai.traceable.io.opentelemetry.javaagent.shaded.org.hypertrace.shaded.com.fasterxml.jackson" )
43154 relocate(" org.yaml" , " ai.traceable.io.opentelemetry.javaagent.shaded.org.hypertrace.shaded.org.yaml" )
44155
45- relocate(" io.opentelemetry" , " ai.traceable.io.opentelemetry" )
46-
47156 // prevents conflict with library instrumentation
48- // relocate("io.opentelemetry.instrumentation.api", "io.opentelemetry.javaagent.shaded.instrumentation.api")
157+ relocate(" io.opentelemetry.instrumentation.api" , " ai.traceable. io.opentelemetry.javaagent.shaded.instrumentation.api" )
49158
50159 // relocate OpenTelemetry API
51- // relocate("io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api")
52- // relocate("io.opentelemetry.semconv", "io.opentelemetry.javaagent.shaded.io.opentelemetry.semconv")
53- // relocate("io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi")
54- // relocate("io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context")
55- // relocate("io.opentelemetry.extension.kotlin", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin")
56- // relocate("io.opentelemetry.extension.aws", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.aws")
160+ relocate(" io.opentelemetry.api" , " ai.traceable.io.opentelemetry.javaagent.shaded.io.opentelemetry.api" )
161+ relocate(" io.opentelemetry.semconv" , " ai.traceable.io.opentelemetry.javaagent.shaded.io.opentelemetry.semconv" )
162+ relocate(" io.opentelemetry.spi" , " ai.traceable.io.opentelemetry.javaagent.shaded.io.opentelemetry.spi" )
163+ relocate(" io.opentelemetry.context" , " ai.traceable.io.opentelemetry.javaagent.shaded.io.opentelemetry.context" )
164+ relocate(" io.opentelemetry.extension.kotlin" , " ai.traceable.io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin" )
165+ relocate(" io.opentelemetry.extension.aws" , " ai.traceable.io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.aws" )
166+ // Shade everything else of io.opentelemetry into ai.traceable.io.opentelemetry
167+ relocate(" io.opentelemetry" , " ai.traceable.io.opentelemetry" )
57168
58169 mergeServiceFiles {
59170 include(" inst/META-INF/services/*" )
@@ -63,7 +174,7 @@ tasks {
63174 // Fix CVE-2024-7254, opentelemetry-javaagent brings in io.prometheus.metrics which uses deps of high vulnerability protobuf-java version
64175 // This was fixed in 2.x.x versions of opentelemetry-javaagent(which needs us to upgrade from 1.33.0)
65176 // TODO: Remove this exclusion after otel-javaagent upgrade which has CVE-2024-7254 fix
66- exclude(" inst/io/prometheus/metrics/shaded/com_google_protobuf_3_21_7/**" )
177+ exclude(" inst/ai/traceable/ io/prometheus/metrics/shaded/com_google_protobuf_3_21_7/**" )
67178 exclude(" **/module-info.class" )
68179 manifest {
69180 attributes.put(" Implementation-Title" , " javaagent" )
0 commit comments