| plugins { |
| id 'com.github.johnrengelman.shadow' version '2.0.1' |
| id 'me.tatarka.retrolambda' version '3.6.0' |
| id 'me.champeau.gradle.jmh' version '0.4.4' |
| id 'io.morethan.jmhreport' version '0.5.0' |
| } |
| |
| description = 'OpenCensus Agent' |
| |
| sourceCompatibility = JavaVersion.VERSION_1_7 |
| targetCompatibility = JavaVersion.VERSION_1_7 |
| |
| // Experimental support for legacy Java 1.6 JVMs. Animalsniffer (applied by the root project) is |
| // used to check for unexpected references to later APIs. Also see dependencies/signature. |
| // Retrolambda itself requires JDK 8, which it finds at $JAVA8_HOME. |
| retrolambda { |
| javaVersion JavaVersion.VERSION_1_6 |
| } |
| |
| def agentPackage = 'io.opencensus.contrib.agent' |
| def agentMainClass = "${agentPackage}.AgentMain" |
| |
| // The package containing the classes that need to be loaded by the bootstrap classloader because |
| // they are used from classes loaded by the bootstrap classloader. |
| def agentBootstrapPackage = "${agentPackage}.bootstrap" |
| def agentBootstrapPackageDir = agentBootstrapPackage.replace('.', '/') + '/' |
| def agentBootstrapClasses = agentBootstrapPackageDir + '**' |
| |
| // The package to which we relocate all third party packages. This avoids any conflicts of the |
| // agent's classes with the app's classes, which are loaded by the same classloader (the system |
| // classloader). |
| def agentRepackaged = "${agentPackage}.deps" |
| |
| dependencies { |
| compileOnly libraries.auto_service |
| compileOnly libraries.grpc_context |
| compile libraries.findbugs_annotations |
| compile libraries.guava |
| compile libraries.byte_buddy |
| |
| signature 'org.codehaus.mojo.signature:java16:+@signature' |
| } |
| |
| jar { |
| manifest { |
| // Set the required manifest attributes for the Java agent, cf. |
| // https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html. |
| attributes 'Premain-Class': agentMainClass |
| attributes 'Can-Retransform-Classes': true |
| |
| // Let the java plugin use the overridden values instead of the root project's values. |
| attributes 'Source-Compatibility': JavaVersion.VERSION_1_6 |
| attributes 'Target-Compatibility': JavaVersion.VERSION_1_6 |
| } |
| } |
| |
| // Create bootstrap.jar containing the classes that need to be loaded by the bootstrap |
| // classloader. |
| task bootstrapJar(type: Jar) { |
| // Output to 'bootstrap.jar'. |
| baseName = 'bootstrap' |
| version = null |
| |
| from sourceSets.main.output |
| include agentBootstrapClasses |
| } |
| |
| shadowJar.dependsOn bootstrapJar |
| |
| // Bundle the agent's classes and dependencies into a single, self-contained JAR file. |
| shadowJar { |
| // Output to opencensus-contrib-agent-VERSION.jar. |
| classifier = null |
| |
| // Include only the following dependencies (excluding transitive dependencies). |
| dependencies { |
| include(dependency(libraries.byte_buddy)) |
| include(dependency(libraries.guava)) |
| } |
| |
| // Exclude cruft which still snuck in. |
| exclude 'META-INF/maven/**' |
| exclude agentBootstrapClasses |
| |
| // Relocate third party packages to avoid any conflicts of the agent's classes with the app's |
| // classes, which are loaded by the same classloader (the system classloader). |
| // Byte Buddy: |
| relocate 'net.bytebuddy', agentRepackaged + '.bytebuddy' |
| // Guava: |
| relocate 'com.google.common', agentRepackaged + '.guava' |
| relocate 'com.google.thirdparty.publicsuffix', agentRepackaged + '.publicsuffix' |
| |
| doLast { |
| def agentPackageDir = agentPackage.replace('.', '/') + '/' |
| def agentBootstrapJar = agentPackageDir + 'bootstrap.jar' |
| |
| // Bundle bootstrap.jar. |
| ant.jar(update: 'true', destfile: shadowJar.archivePath) { |
| mappedresources { |
| fileset(file: bootstrapJar.archivePath) |
| globmapper(from: '*', to: agentBootstrapJar) |
| } |
| } |
| |
| // Assert that there's nothing obviously wrong with the JAR's contents. |
| new java.util.zip.ZipFile(shadowJar.archivePath).withCloseable { |
| // Must have bundled the bootstrap.jar. |
| assert it.entries().any { it.name == agentBootstrapJar } |
| |
| it.entries().each { entry -> |
| // Must not contain anything outside of ${agentPackage}, ... |
| assert entry.name.startsWith(agentPackageDir) || |
| // ... except for the expected entries. |
| [ agentPackageDir, |
| 'META-INF/MANIFEST.MF', |
| 'META-INF/services/io.opencensus.contrib.agent.instrumentation.Instrumenter' |
| ].any { entry.isDirectory() ? it.startsWith(entry.name) : it == entry.name } |
| // Also, should not have the bootstrap classes. |
| assert !entry.name.startsWith(agentBootstrapPackageDir) |
| } |
| } |
| } |
| } |
| |
| jar.finalizedBy shadowJar |
| |
| // TODO(stschmidt): Proguard-shrink the agent JAR. |
| |
| // Integration tests. The setup is mostly based on |
| // https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/. |
| |
| sourceSets { |
| integrationTest { |
| java { |
| compileClasspath += main.output + test.output |
| runtimeClasspath += main.output + test.output |
| srcDir file('src/integration-test/java') |
| } |
| resources.srcDir file('src/integration-test/resources') |
| } |
| } |
| |
| configurations { |
| integrationTestCompile.extendsFrom testCompile |
| integrationTestRuntime.extendsFrom testRuntime |
| } |
| |
| dependencies { |
| integrationTestCompile libraries.grpc_context |
| } |
| |
| // Disable checkstyle for integration tests if not java8. |
| checkstyleIntegrationTest.enabled = JavaVersion.current().isJava8Compatible() |
| |
| // Disable findbugs for integration tests, too. |
| findbugsIntegrationTest.enabled = false |
| |
| // Run integration tests with the agent enabled. |
| task integrationTest(type: Test) { |
| testLogging { |
| // Let Gradle output the stdout and stderr from tests, too. This is useful for investigating |
| // test failures on Travis, where we can't view Gradle's test reports. |
| showStandardStreams = true |
| |
| // Include the exception message and full stacktrace for failed tests. |
| exceptionFormat 'full' |
| } |
| |
| testClassesDirs = sourceSets.integrationTest.output.classesDirs |
| classpath = sourceSets.integrationTest.runtimeClasspath |
| |
| jvmArgs "-javaagent:${shadowJar.archivePath}" |
| } |
| |
| check.dependsOn integrationTest |
| integrationTest.dependsOn shadowJar |
| integrationTest.mustRunAfter test |
| |
| // JMH benchmarks |
| |
| dependencies { |
| jmh libraries.grpc_context |
| } |
| |
| // Disable checkstyle for JMH benchmarks if not java8. |
| checkstyleJmh.enabled = JavaVersion.current().isJava8Compatible() |
| |
| // Generate html report for findbugsJmh. |
| findbugsJmh { |
| reports { |
| xml.enabled = false |
| html.enabled = true |
| } |
| } |
| |
| // Make the agent JAR available using a fixed file name so that we don't have to modify the JMH |
| // benchmarks whenever the version changes. |
| task agentJar(type: Copy) { |
| dependsOn shadowJar |
| |
| from shadowJar.archivePath |
| into libsDir |
| rename { 'agent.jar' } |
| } |
| |
| jmhJar.dependsOn agentJar |
| jmhJar.dependsOn integrationTest |
| |
| jmh { |
| jmhVersion = '1.19' |
| warmupIterations = 10 |
| iterations = 10 |
| fork = 1 |
| failOnError = true |
| resultFormat = 'JSON' |
| } |
| |
| jmhReport { |
| jmhResultPath = project.file("${project.buildDir}/reports/jmh/results.json") |
| jmhReportOutput = project.file("${project.buildDir}/reports/jmh") |
| } |
| |
| tasks.jmh.finalizedBy tasks.jmhReport |