1buildscript {
2    repositories {
3        mavenCentral()
4        mavenLocal()
5        maven {
6            url "https://plugins.gradle.org/m2/"
7        }
8    }
9    dependencies {
10        classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.4.6'
11        classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.16'
12        classpath "net.ltgt.gradle:gradle-apt-plugin:0.18"
13        classpath 'com.github.ben-manes:gradle-versions-plugin:0.20.0'
14        classpath "gradle.plugin.com.github.sherter.google-java-format:google-java-format-gradle-plugin:0.7.1"
15        classpath "me.champeau.gradle:jmh-gradle-plugin:0.4.7"
16        classpath "gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.7.0"
17    }
18}
19
20// Display the version report using: ./gradlew dependencyUpdates
21// Also see https://github.com/ben-manes/gradle-versions-plugin.
22apply plugin: 'com.github.ben-manes.versions'
23
24// Don't use the Checker Framework by default, since it interferes with Error Prone.
25def useCheckerFramework = rootProject.hasProperty('checkerFramework')
26def useErrorProne = !useCheckerFramework
27
28subprojects {
29    apply plugin: "checkstyle"
30    apply plugin: 'maven'
31    apply plugin: 'idea'
32    apply plugin: 'eclipse'
33    apply plugin: 'java'
34    apply plugin: "signing"
35    apply plugin: "jacoco"
36    // The plugin only has an effect if a signature is specified
37    apply plugin: 'ru.vyarus.animalsniffer'
38    apply plugin: 'findbugs'
39    apply plugin: 'net.ltgt.apt'
40    apply plugin: "me.champeau.gradle.jmh"
41    apply plugin: "io.morethan.jmhreport"
42    // Plugins that require java8
43    if (JavaVersion.current().isJava8Compatible()) {
44        if (useErrorProne) {
45            apply plugin: "net.ltgt.errorprone"
46        }
47        apply plugin: 'com.github.sherter.google-java-format'
48    }
49
50    group = "io.opencensus"
51    version = "0.17.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION
52
53    sourceCompatibility = 1.6
54    targetCompatibility = 1.6
55
56    repositories {
57        mavenCentral()
58        mavenLocal()
59    }
60
61    if (useCheckerFramework) {
62        configurations {
63            checkerFrameworkJavac {
64                description = 'a customization of the Open JDK javac compiler with additional support for type annotations'
65            }
66            checkerFrameworkAnnotatedJDK {
67                description = 'a copy of JDK classes with Checker Framework type qualifiers inserted'
68            }
69        }
70    }
71
72    [compileJava, compileTestJava, compileJmhJava].each() {
73        // We suppress the "try" warning because it disallows managing an auto-closeable with
74        // try-with-resources without referencing the auto-closeable within the try block.
75        // We suppress the "processing" warning as suggested in
76        // https://groups.google.com/forum/#!topic/bazel-discuss/_R3A9TJSoPM
77        it.options.compilerArgs += ["-Xlint:all", "-Xlint:-try", "-Xlint:-processing"]
78        if (useErrorProne) {
79            if (JavaVersion.current().isJava8Compatible()) {
80                it.options.compilerArgs += ["-XepAllDisabledChecksAsWarnings", "-XepDisableWarningsInGeneratedCode"]
81
82                // MutableMethodReturnType can suggest returning Guava types from
83                // API methods (https://github.com/google/error-prone/issues/982).
84                it.options.compilerArgs += ["-Xep:MutableMethodReturnType:OFF"]
85
86                // ReturnMissingNullable conflicts with Checker Framework null analysis.
87                it.options.compilerArgs += ["-Xep:ReturnMissingNullable:OFF"]
88
89                // OpenCensus doesn't currently use Var annotations.
90                it.options.compilerArgs += ["-Xep:Var:OFF"]
91            }
92        }
93        if (useCheckerFramework) {
94            it.options.compilerArgs += [
95                '-processor',
96		'com.google.auto.value.processor.AutoValueProcessor,org.checkerframework.checker.nullness.NullnessChecker',
97		"-Astubs=$rootDir/checker-framework/stubs"
98            ]
99        }
100        it.options.encoding = "UTF-8"
101        // Protobuf-generated code produces some warnings.
102        // https://github.com/google/protobuf/issues/2718
103        it.options.compilerArgs += ["-Xlint:-cast"]
104        if (!JavaVersion.current().isJava9()) {
105            // TODO(sebright): Enable -Werror for Java 9 once we upgrade AutoValue (issue #1017).
106            it.options.compilerArgs += ["-Werror"]
107        }
108        if (JavaVersion.current().isJava7()) {
109            // Suppress all deprecation warnings with Java 7, since there are some bugs in its handling of
110            // @SuppressWarnings. See
111            // https://stackoverflow.com/questions/26921774/how-to-avoid-deprecation-warnings-when-suppresswarningsdeprecation-doesnt
112            it.options.compilerArgs += ["-Xlint:-deprecation"]
113
114            // TODO(bdrutu): Enable for Java 7 when fix the issue with configuring bootstrap class.
115            // [options] bootstrap class path not set in conjunction with -source 1.6
116            it.options.compilerArgs += ["-Xlint:-options"]
117        }
118        if (JavaVersion.current().isJava9()) {
119            // TODO(sebright): Currently, building with Java 9 produces the following "options" warnings:
120            //
121            // :opencensus-api:compileJavawarning: [options] bootstrap class path not set in conjunction with -source 1.6
122            // warning: [options] source value 1.6 is obsolete and will be removed in a future release
123            // warning: [options] target value 1.6 is obsolete and will be removed in a future release
124            it.options.compilerArgs += ["-Xlint:-options"]
125        }
126    }
127
128    compileTestJava {
129        // serialVersionUID is basically guaranteed to be useless in tests
130        options.compilerArgs += ["-Xlint:-serial"]
131        // It undeprecates DoubleSubject.isEqualTo(Double).
132        options.compilerArgs += ["-Xlint:-deprecation"]
133    }
134
135    jar.manifest {
136        attributes('Implementation-Title': name,
137                'Implementation-Version': version,
138                'Built-By': System.getProperty('user.name'),
139                'Built-JDK': System.getProperty('java.version'),
140                'Source-Compatibility': sourceCompatibility,
141                'Target-Compatibility': targetCompatibility)
142    }
143
144    javadoc.options {
145        encoding = 'UTF-8'
146        links 'https://docs.oracle.com/javase/8/docs/api/'
147    }
148
149    ext {
150        appengineVersion = '1.9.64'
151        aspectjVersion = '1.8.11'
152        autoValueVersion = '1.4'
153        findBugsAnnotationsVersion = '3.0.1'
154        findBugsJsr305Version = '3.0.2'
155        errorProneVersion = '2.3.1'
156        grpcVersion = '1.14.0'
157        guavaVersion = '20.0'
158        googleAuthVersion = '0.11.0'
159        googleCloudBetaVersion = '0.64.0-beta'
160        googleCloudGaVersion = '1.46.0'
161        log4j2Version = '2.11.1'
162        signalfxVersion = '0.0.39'
163        springBootVersion = '1.5.15.RELEASE'
164        springCloudVersion = '1.3.4.RELEASE'
165        springVersion = '4.3.12.RELEASE'
166        prometheusVersion = '0.4.0'
167        protobufVersion = '3.5.1'
168        zipkinReporterVersion = '2.3.2'
169        jaegerReporterVersion = '0.27.0'
170        opencensusProtoVersion = '0.0.2'
171        dropwizardVersion = '3.1.2'
172
173        libraries = [
174                appengine_api: "com.google.appengine:appengine-api-1.0-sdk:${appengineVersion}",
175                aspectj: "org.aspectj:aspectjrt:${aspectjVersion}",
176                auto_value: "com.google.auto.value:auto-value:${autoValueVersion}",
177                auto_service: 'com.google.auto.service:auto-service:1.0-rc3',
178                byte_buddy: 'net.bytebuddy:byte-buddy:1.7.11',
179                config: 'com.typesafe:config:1.2.1',
180                disruptor: 'com.lmax:disruptor:3.4.1',
181                errorprone: "com.google.errorprone:error_prone_annotations:${errorProneVersion}",
182                findbugs_annotations: "com.google.code.findbugs:annotations:${findBugsAnnotationsVersion}",
183                google_auth: "com.google.auth:google-auth-library-credentials:${googleAuthVersion}",
184                google_cloud_logging: "com.google.cloud:google-cloud-logging:${googleCloudGaVersion}",
185                google_cloud_trace: "com.google.cloud:google-cloud-trace:${googleCloudBetaVersion}",
186                log4j2: "org.apache.logging.log4j:log4j-core:${log4j2Version}",
187                zipkin_reporter: "io.zipkin.reporter2:zipkin-reporter:${zipkinReporterVersion}",
188                zipkin_urlconnection: "io.zipkin.reporter2:zipkin-sender-urlconnection:${zipkinReporterVersion}",
189                jaeger_reporter: "com.uber.jaeger:jaeger-core:${jaegerReporterVersion}",
190                google_cloud_monitoring: "com.google.cloud:google-cloud-monitoring:${googleCloudGaVersion}",
191                grpc_context: "io.grpc:grpc-context:${grpcVersion}",
192                grpc_core: "io.grpc:grpc-core:${grpcVersion}",
193                grpc_netty: "io.grpc:grpc-netty:${grpcVersion}",
194                grpc_stub: "io.grpc:grpc-stub:${grpcVersion}",
195                guava: "com.google.guava:guava:${guavaVersion}",
196                jsr305: "com.google.code.findbugs:jsr305:${findBugsJsr305Version}",
197                signalfx_java: "com.signalfx.public:signalfx-java:${signalfxVersion}",
198                spring_aspects: "org.springframework:spring-aspects:${springVersion}",
199                spring_boot_starter_web: "org.springframework.boot:spring-boot-starter-web:${springBootVersion}",
200                spring_cloud_build: "org.springframework.cloud:spring-cloud-build:${springCloudVersion}",
201                spring_cloud_starter_sleuth: "org.springframework.cloud:spring-cloud-starter-sleuth:${springCloudVersion}",
202                spring_context: "org.springframework:spring-context:${springVersion}",
203                spring_context_support: "org.springframework:spring-context-support:${springVersion}",
204                prometheus_simpleclient: "io.prometheus:simpleclient:${prometheusVersion}",
205                protobuf: "com.google.protobuf:protobuf-java:${protobufVersion}",
206                opencensus_proto: "io.opencensus:opencensus-proto:${opencensusProtoVersion}",
207
208                // Test dependencies.
209                guava_testlib: "com.google.guava:guava-testlib:${guavaVersion}",
210                junit: 'junit:junit:4.12',
211                mockito: 'org.mockito:mockito-core:1.9.5',
212                spring_test: "org.springframework:spring-test:${springVersion}",
213                truth: 'com.google.truth:truth:0.30',
214                dropwizard: "io.dropwizard.metrics:metrics-core:${dropwizardVersion}",
215        ]
216    }
217
218    configurations {
219        compile {
220            // Detect Maven Enforcer's dependencyConvergence failures. We only
221            // care for artifacts used as libraries by others.
222            if (!(project.name in ['benchmarks', 'opencensus-all',
223                                   'opencensus-exporter-stats-stackdriver',
224                                   'opencensus-exporter-trace-stackdriver',
225                                   'opencensus-exporter-trace-jaeger'])) {
226                resolutionStrategy.failOnVersionConflict()
227            }
228        }
229    }
230
231    dependencies {
232        if (useCheckerFramework) {
233            ext.checkerFrameworkVersion = '2.5.5'
234
235            // 2.4.0 is the last version of the Checker Framework compiler that supports annotations
236            // in comments, though it should continue to work with newer versions of the Checker Framework.
237            // See
238            // https://github.com/census-instrumentation/opencensus-java/pull/1112#issuecomment-381366366.
239            ext.checkerFrameworkCompilerVersion = '2.4.0'
240
241            ext.jdkVersion = 'jdk8'
242            checkerFrameworkAnnotatedJDK "org.checkerframework:${jdkVersion}:${checkerFrameworkVersion}"
243            checkerFrameworkJavac "org.checkerframework:compiler:${checkerFrameworkCompilerVersion}"
244            compileOnly "org.checkerframework:checker:${checkerFrameworkVersion}"
245            compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
246            compileOnly libraries.auto_value
247        }
248
249        compileOnly libraries.errorprone,
250                    libraries.jsr305
251
252        testCompile libraries.guava_testlib,
253                libraries.junit,
254                libraries.mockito,
255                libraries.truth
256
257    if (useErrorProne && JavaVersion.current().isJava8Compatible()) {
258            // The ErrorProne plugin defaults to the latest, which would break our
259            // build if error prone releases a new version with a new check
260            errorprone "com.google.errorprone:error_prone_core:${errorProneVersion}"
261        }
262    }
263
264    findbugs {
265        toolVersion = findBugsAnnotationsVersion
266        ignoreFailures = false   // bug free or it doesn't ship!
267        effort = 'max'
268        reportLevel = 'low'      // low = sensitive to even minor mistakes
269        omitVisitors = []        // bugs that we want to ignore
270        excludeFilter = file("$rootDir/findbugs-exclude.xml")
271    }
272    // Generate html report for findbugs.
273    findbugsMain {
274        reports {
275            xml.enabled = false
276            html.enabled = true
277        }
278    }
279    findbugsTest {
280        reports {
281            xml.enabled = false
282            html.enabled = true
283        }
284    }
285    findbugsJmh {
286        reports {
287            xml.enabled = false
288            html.enabled = true
289        }
290    }
291
292    checkstyle {
293        configFile = file("$rootDir/buildscripts/checkstyle.xml")
294        toolVersion = "8.12"
295        ignoreFailures = false
296        if (rootProject.hasProperty("checkstyle.ignoreFailures")) {
297            ignoreFailures = rootProject.properties["checkstyle.ignoreFailures"].toBoolean()
298        }
299        configProperties["rootDir"] = rootDir
300    }
301
302    // Disable checkstyle if no java8.
303    checkstyleMain.enabled = JavaVersion.current().isJava8Compatible()
304    checkstyleTest.enabled = JavaVersion.current().isJava8Compatible()
305    checkstyleJmh.enabled = JavaVersion.current().isJava8Compatible()
306
307    // Google formatter works only on java8.
308    if (JavaVersion.current().isJava8Compatible()) {
309        googleJavaFormat {
310            toolVersion '1.6'
311        }
312
313        afterEvaluate {  // Allow subproject to add more source sets.
314            tasks.googleJavaFormat {
315                source = sourceSets*.allJava
316                include '**/*.java'
317            }
318
319            tasks.verifyGoogleJavaFormat {
320                source = sourceSets*.allJava
321                include '**/*.java'
322            }
323        }
324    }
325
326    signing {
327        required false
328        sign configurations.archives
329    }
330
331    task javadocJar(type: Jar) {
332        classifier = 'javadoc'
333        from javadoc
334    }
335
336    task sourcesJar(type: Jar) {
337        classifier = 'sources'
338        from sourceSets.main.allSource
339    }
340
341    artifacts {
342        archives javadocJar, sourcesJar
343    }
344
345    jmh {
346        jmhVersion = '1.20'
347        warmupIterations = 10
348        iterations = 10
349        fork = 1
350        failOnError = true
351        resultFormat = 'JSON'
352        // Allow to run single benchmark class like:
353        // ./gradlew -PjmhIncludeSingleClass=StatsTraceContextBenchmark clean :grpc-core:jmh
354        if (project.hasProperty('jmhIncludeSingleClass')) {
355            include = [
356                    project.property('jmhIncludeSingleClass')
357            ]
358        }
359    }
360
361    jmhReport {
362        jmhResultPath = project.file("${project.buildDir}/reports/jmh/results.json")
363        jmhReportOutput = project.file("${project.buildDir}/reports/jmh")
364    }
365
366    tasks.jmh.finalizedBy tasks.jmhReport
367
368    uploadArchives {
369        repositories {
370            mavenDeployer {
371                beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
372
373                def configureAuth = {
374                    if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) {
375                        authentication(userName:rootProject.ossrhUsername, password: rootProject.ossrhPassword)
376                    }
377                }
378
379                repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/", configureAuth)
380
381                snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/", configureAuth)
382
383                pom.project {
384                    name "OpenCensus"
385                    packaging 'jar'
386                    description project.description
387                    url 'https://github.com/census-instrumentation/opencensus-java'
388
389                    scm {
390                        connection 'scm:svn:https://github.com/census-instrumentation/opencensus-java'
391                        developerConnection 'scm:git:git@github.com/census-instrumentation/opencensus-java'
392                        url 'https://github.com/census-instrumentation/opencensus-java'
393                    }
394
395                    licenses {
396                        license {
397                            name 'The Apache License, Version 2.0'
398                            url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
399                        }
400                    }
401
402                    developers {
403                        developer {
404                            id 'io.opencensus'
405                            name 'OpenCensus Contributors'
406                            email 'census-developers@googlegroups.com'
407                            url 'opencensus.io'
408                            // https://issues.gradle.org/browse/GRADLE-2719
409                            organization = 'OpenCensus Authors'
410                            organizationUrl 'https://www.opencensus.io'
411                        }
412                    }
413                }
414            }
415        }
416    }
417
418    // Upload the following artifacts only:
419    uploadArchives.onlyIf {
420        name in ['opencensus-api',
421                 'opencensus-contrib-agent',
422                 'opencensus-contrib-appengine-standard-util',
423                 'opencensus-contrib-dropwizard',
424                 'opencensus-contrib-exemplar-util',
425                 'opencensus-contrib-grpc-metrics',
426                 'opencensus-contrib-grpc-util',
427                 'opencensus-contrib-http-util',
428                 'opencensus-contrib-log-correlation-log4j2',
429                 'opencensus-contrib-log-correlation-stackdriver',
430                 'opencensus-contrib-monitored-resource-util',
431                 'opencensus-contrib-spring',
432                 'opencensus-contrib-spring-sleuth-v1x',
433                 'opencensus-contrib-zpages',
434                 'opencensus-exporter-stats-prometheus',
435                 'opencensus-exporter-stats-signalfx',
436                 'opencensus-exporter-stats-stackdriver',
437                 'opencensus-exporter-trace-instana',
438                 'opencensus-exporter-trace-logging',
439                 'opencensus-exporter-trace-ocagent',
440                 'opencensus-exporter-trace-stackdriver',
441                 'opencensus-exporter-trace-zipkin',
442                 'opencensus-exporter-trace-jaeger',
443                 'opencensus-impl-core',
444                 'opencensus-impl-lite',
445                 'opencensus-impl',
446                 'opencensus-testing']
447    }
448
449    // At a test failure, log the stack trace to the console so that we don't
450    // have to open the HTML in a browser.
451    test {
452        testLogging {
453            exceptionFormat = 'full'
454            showExceptions true
455            showCauses true
456            showStackTraces true
457        }
458        maxHeapSize = '1500m'
459    }
460
461    if (useCheckerFramework) {
462        allprojects {
463            tasks.withType(JavaCompile).all { JavaCompile compile ->
464                compile.doFirst {
465                    compile.options.compilerArgs += [
466                        '-Xmaxerrs', '10000',
467                        "-Xbootclasspath/p:${configurations.checkerFrameworkAnnotatedJDK.asPath}",
468                        "-AskipDefs=\\.AutoValue_|^io.opencensus.contrib.appengine.standard.util.TraceIdProto\$|^io.opencensus.contrib.appengine.standard.util.TraceProto\$",
469                        "-AinvariantArrays"
470                    ]
471                    options.fork = true
472                    options.forkOptions.jvmArgs += ["-Xbootclasspath/p:${configurations.checkerFrameworkJavac.asPath}"]
473                }
474            }
475        }
476    }
477
478    // For projects that depend on gRPC during test execution, make sure to
479    // also configure ALPN if running on a platform (e.g. FreeBSD) that is not
480    // supported by io.netty:netty-tcnative-boringssl-static:jar. Also see:
481    // https://github.com/grpc/grpc-java/blob/master/SECURITY.md#tls-with-jdk-jetty-alpnnpn
482    if (project.name in ['opencensus-exporter-stats-stackdriver',
483                         'opencensus-exporter-trace-stackdriver']) {
484        def os = org.gradle.internal.os.OperatingSystem.current()
485        if (!os.isLinux() && !os.isWindows() && !os.isMacOsX()) {
486            configurations {
487                alpn
488            }
489            dependencies {
490                alpn 'org.mortbay.jetty.alpn:jetty-alpn-agent:2.0.7'
491            }
492            test {
493                jvmArgs "-javaagent:${configurations.alpn.asPath}"
494            }
495        }
496    }
497}
498