You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
8.1 KiB
247 lines
8.1 KiB
plugins {
|
|
id 'com.github.johnrengelman.shadow' version '2.0.2'
|
|
}
|
|
|
|
description = 'OpenCensus Agent'
|
|
|
|
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
|
|
compileOnly project(':opencensus-api')
|
|
compile libraries.byte_buddy
|
|
compile libraries.config
|
|
compile libraries.findbugs_annotations
|
|
compile libraries.guava
|
|
|
|
signature 'org.codehaus.mojo.signature:java17:1.0@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
|
|
}
|
|
}
|
|
|
|
// 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.config))
|
|
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'
|
|
// Config:
|
|
relocate 'com.typesafe.config', agentRepackaged + '.config'
|
|
// 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',
|
|
'reference.conf',
|
|
].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 was initially based on
|
|
// https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/.
|
|
// We run the same suite of integration tests on different Java versions with the agent enabled.
|
|
// The JAVA_HOMES environment variable lists the home directories of the Java installations used
|
|
// for integration testing.
|
|
|
|
// The default JAR has been replaced with a self-contained JAR by the shadowJar task. Therefore,
|
|
// remove all declared dependencies from the generated Maven POM for said JAR.
|
|
uploadArchives {
|
|
repositories {
|
|
mavenDeployer {
|
|
pom.whenConfigured {
|
|
dependencies = []
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 project(':opencensus-api')
|
|
integrationTestCompile project(':opencensus-testing')
|
|
integrationTestRuntime libraries.grpc_context
|
|
integrationTestRuntime project(':opencensus-impl-lite')
|
|
}
|
|
|
|
// Disable checkstyle for integration tests if not java8.
|
|
checkstyleIntegrationTest.enabled = JavaVersion.current().isJava8Compatible()
|
|
|
|
// Disable findbugs for integration tests, too.
|
|
findbugsIntegrationTest.enabled = false
|
|
|
|
def javaExecutables = (System.getenv('JAVA_HOMES') ?: '')
|
|
.tokenize(File.pathSeparator)
|
|
.plus(System.getProperty('java.home'))
|
|
.collect { org.apache.tools.ant.taskdefs.condition.Os.isFamily(
|
|
org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS)
|
|
? "${it}/bin/java.exe"
|
|
: "${it}/bin/java" }
|
|
.collect { new File(it).getCanonicalPath() }
|
|
.unique()
|
|
|
|
assert javaExecutables.size > 0 :
|
|
'No Java executables found for running integration tests'
|
|
|
|
task integrationTest
|
|
|
|
javaExecutables.eachWithIndex { javaExecutable, index ->
|
|
def perVersionIntegrationTest = task("integrationTest_${index}", 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'
|
|
}
|
|
|
|
dependsOn shadowJar
|
|
|
|
testClassesDirs = sourceSets.integrationTest.output.classesDirs
|
|
classpath = sourceSets.integrationTest.runtimeClasspath
|
|
|
|
executable = javaExecutable
|
|
|
|
// The JaCoCo agent must be specified first so that it can instrument our agent.
|
|
// This is a work around for the issue that the JaCoCo agent is added last, cf.
|
|
// https://discuss.gradle.org/t/jacoco-gradle-adds-the-agent-last-to-jvm-args/7124.
|
|
doFirst {
|
|
jvmArgs jacoco.asJvmArg // JaCoCo agent first.
|
|
jvmArgs "-javaagent:${shadowJar.archivePath}" // Our agent second.
|
|
jacoco.enabled = false // Don't add the JaCoCo agent again.
|
|
}
|
|
|
|
doFirst { logger.lifecycle("Running integration tests using ${javaExecutable}.") }
|
|
}
|
|
|
|
integrationTest.dependsOn perVersionIntegrationTest
|
|
}
|
|
|
|
check.dependsOn integrationTest
|
|
integrationTest.mustRunAfter test
|
|
|
|
// Merge JaCoCo's execution data from all tests into the main test's execution data file.
|
|
task jacocoMerge(type: JacocoMerge) {
|
|
tasks.withType(Test).each { testTask ->
|
|
dependsOn testTask
|
|
executionData testTask.jacoco.destinationFile
|
|
}
|
|
doLast {
|
|
destinationFile.renameTo test.jacoco.destinationFile
|
|
}
|
|
}
|
|
|
|
jacocoTestReport.dependsOn jacocoMerge
|
|
|
|
// JMH benchmarks
|
|
|
|
dependencies {
|
|
jmh libraries.grpc_context
|
|
}
|
|
|
|
// 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
|