Home | History | Annotate | Download | only in grpc-grpc-java
      1 buildscript {
      2     repositories {
      3         mavenLocal()
      4         maven { url "https://plugins.gradle.org/m2/" }
      5     }
      6     dependencies {
      7         classpath "com.diffplug.spotless:spotless-plugin-gradle:3.13.0"
      8         classpath 'com.google.gradle:osdetector-gradle-plugin:1.4.0'
      9         classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.4.5'
     10         classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.13'
     11         classpath 'net.ltgt.gradle:gradle-apt-plugin:0.13'
     12         classpath "me.champeau.gradle:jmh-gradle-plugin:0.4.5"
     13         classpath 'me.champeau.gradle:japicmp-gradle-plugin:0.2.5'
     14     }
     15 }
     16 
     17 subprojects {
     18     apply plugin: "checkstyle"
     19     apply plugin: "java"
     20     apply plugin: "maven"
     21     apply plugin: "idea"
     22     apply plugin: "signing"
     23     apply plugin: "jacoco"
     24 
     25     apply plugin: "me.champeau.gradle.jmh"
     26     apply plugin: "com.google.osdetector"
     27     // The plugin only has an effect if a signature is specified
     28     apply plugin: "ru.vyarus.animalsniffer"
     29     // jdk10 not supported by errorprone: https://github.com/google/error-prone/issues/860
     30     if (!JavaVersion.current().isJava10Compatible() &&
     31         rootProject.properties.get('errorProne', true)) {
     32         apply plugin: "net.ltgt.errorprone"
     33         apply plugin: "net.ltgt.apt"
     34 
     35         dependencies {
     36             // The ErrorProne plugin defaults to the latest, which would break our
     37             // build if error prone releases a new version with a new check
     38             errorprone 'com.google.errorprone:error_prone_core:2.2.0'
     39             apt 'com.google.guava:guava-beta-checker:1.0'
     40         }
     41     } else {
     42         // Remove per-project error-prone checker config
     43         allprojects {
     44             afterEvaluate { project ->
     45                 project.tasks.withType(JavaCompile) {
     46                     options.compilerArgs.removeAll { it.startsWith("-Xep") }
     47                 }
     48             }
     49         }
     50     }
     51     // TODO(zpencer): remove when intellij 2017.2 is released
     52     // https://github.com/gradle/gradle/issues/2315
     53     idea.module.inheritOutputDirs = true
     54 
     55     group = "io.grpc"
     56     version = "1.16.0-SNAPSHOT" // CURRENT_GRPC_VERSION
     57 
     58     sourceCompatibility = 1.7
     59     targetCompatibility = 1.7
     60 
     61     repositories {
     62         maven { // The google mirror is less flaky than mavenCentral()
     63             url "https://maven-central.storage-download.googleapis.com/repos/central/data/" }
     64         mavenLocal()
     65     }
     66 
     67     [
     68         compileJava,
     69         compileTestJava,
     70         compileJmhJava
     71     ].each() {
     72         it.options.compilerArgs += [
     73             "-Xlint:all",
     74             "-Xlint:-options",
     75             "-Xlint:-path",
     76             "-Xlint:-try"
     77         ]
     78         it.options.encoding = "UTF-8"
     79         if (rootProject.hasProperty('failOnWarnings') && rootProject.failOnWarnings.toBoolean()) {
     80             it.options.compilerArgs += ["-Werror"]
     81         }
     82     }
     83 
     84     compileTestJava {
     85         // serialVersionUID is basically guaranteed to be useless in our tests
     86         // LinkedList doesn't hurt much in tests and has lots of usages
     87         options.compilerArgs += [
     88             "-Xlint:-serial",
     89             "-Xep:JdkObsolete:OFF"
     90         ]
     91     }
     92 
     93     jar.manifest {
     94         attributes('Implementation-Title': name,
     95         'Implementation-Version': version,
     96         'Built-By': System.getProperty('user.name'),
     97         'Built-JDK': System.getProperty('java.version'),
     98         'Source-Compatibility': sourceCompatibility,
     99         'Target-Compatibility': targetCompatibility)
    100     }
    101 
    102     javadoc.options {
    103         encoding = 'UTF-8'
    104         use = true
    105         links 'https://docs.oracle.com/javase/8/docs/api/'
    106     }
    107 
    108     ext {
    109         def exeSuffix = osdetector.os == 'windows' ? ".exe" : ""
    110         protocPluginBaseName = 'protoc-gen-grpc-java'
    111         javaPluginPath = "$rootDir/compiler/build/exe/java_plugin/$protocPluginBaseName$exeSuffix"
    112 
    113         nettyVersion = '4.1.27.Final'
    114         guavaVersion = '20.0'
    115         protobufVersion = '3.5.1'
    116         protocVersion = '3.5.1-1'
    117         protobufNanoVersion = '3.0.0-alpha-5'
    118         opencensusVersion = '0.12.3'
    119 
    120         configureProtoCompilation = {
    121             String generatedSourcePath = "${projectDir}/src/generated"
    122             if (rootProject.childProjects.containsKey('grpc-compiler')) {
    123                 // Only when the codegen is built along with the project, will we be able to recompile
    124                 // the proto files.
    125                 project.apply plugin: 'com.google.protobuf'
    126                 project.protobuf {
    127                     protoc {
    128                         if (project.hasProperty('protoc')) {
    129                             path = project.protoc
    130                         } else {
    131                             artifact = "com.google.protobuf:protoc:${protocVersion}"
    132                         }
    133                     }
    134                     plugins { grpc { path = javaPluginPath } }
    135                     generateProtoTasks {
    136                         all().each { task ->
    137                             task.dependsOn ':grpc-compiler:java_pluginExecutable'
    138                             // Delete the generated sources first, so that we can be alerted if they are not re-compiled.
    139                             task.dependsOn 'deleteGeneratedSource' + task.sourceSet.name
    140                             // Recompile protos when the codegen has been changed
    141                             task.inputs.file javaPluginPath
    142                             // Recompile protos when build.gradle has been changed, because
    143                             // it's possible the version of protoc has been changed.
    144                             task.inputs.file "${rootProject.projectDir}/build.gradle"
    145                             task.plugins { grpc { option 'noversion' } }
    146                         }
    147                     }
    148                     generatedFilesBaseDir = generatedSourcePath
    149                 }
    150 
    151                 sourceSets.each { sourceSet ->
    152                     task "deleteGeneratedSource${sourceSet.name}" {
    153                         doLast {
    154                             project.delete project.fileTree(dir: generatedSourcePath + '/' + sourceSet.name)
    155                         }
    156                     }
    157                 }
    158             } else {
    159                 // Otherwise, we just use the checked-in generated code.
    160                 project.sourceSets {
    161                     main {
    162                         java {
    163                             srcDir "${generatedSourcePath}/main/java"
    164                             srcDir "${generatedSourcePath}/main/javanano"
    165                             srcDir "${generatedSourcePath}/main/grpc"
    166                         }
    167                     }
    168                     test {
    169                         java {
    170                             srcDir "${generatedSourcePath}/test/java"
    171                             srcDir "${generatedSourcePath}/test/javanano"
    172                             srcDir "${generatedSourcePath}/test/grpc"
    173                         }
    174                     }
    175                 }
    176             }
    177 
    178             [
    179                 compileJava,
    180                 compileTestJava,
    181                 compileJmhJava
    182             ].each() {
    183                 // Protobuf-generated code produces some warnings.
    184                 // https://github.com/google/protobuf/issues/2718
    185                 it.options.compilerArgs += [
    186                     "-Xlint:-cast",
    187                     "-XepExcludedPaths:.*/src/generated/[^/]+/java/.*",
    188                 ]
    189             }
    190         }
    191 
    192         def epoll_suffix = "";
    193         if (osdetector.classifier in ["linux-x86_64"]) {
    194             // The native code is only pre-compiled on certain platforms.
    195             epoll_suffix = ":" + osdetector.classifier
    196         }
    197         libraries = [
    198             animalsniffer_annotations: "org.codehaus.mojo:animal-sniffer-annotations:1.17",
    199             errorprone: "com.google.errorprone:error_prone_annotations:2.2.0",
    200             gson: "com.google.code.gson:gson:2.7",
    201             guava: "com.google.guava:guava:${guavaVersion}",
    202             hpack: 'com.twitter:hpack:0.10.1',
    203             javax_annotation: 'javax.annotation:javax.annotation-api:1.2',
    204             jsr305: 'com.google.code.findbugs:jsr305:3.0.0',
    205             oauth_client: 'com.google.auth:google-auth-library-oauth2-http:0.9.0',
    206             google_api_protos: 'com.google.api.grpc:proto-google-common-protos:1.0.0',
    207             google_auth_credentials: 'com.google.auth:google-auth-library-credentials:0.9.0',
    208             google_auth_oauth2_http: 'com.google.auth:google-auth-library-oauth2-http:0.9.0',
    209             okhttp: 'com.squareup.okhttp:okhttp:2.5.0',
    210             okio: 'com.squareup.okio:okio:1.13.0',
    211             opencensus_api: "io.opencensus:opencensus-api:${opencensusVersion}",
    212             opencensus_contrib_grpc_metrics: "io.opencensus:opencensus-contrib-grpc-metrics:${opencensusVersion}",
    213             opencensus_impl: "io.opencensus:opencensus-impl:${opencensusVersion}",
    214             opencensus_impl_lite: "io.opencensus:opencensus-impl-lite:${opencensusVersion}",
    215             instrumentation_api: 'com.google.instrumentation:instrumentation-api:0.4.3',
    216             protobuf: "com.google.protobuf:protobuf-java:${protobufVersion}",
    217             protobuf_lite: "com.google.protobuf:protobuf-lite:3.0.1",
    218             protoc_lite: "com.google.protobuf:protoc-gen-javalite:3.0.0",
    219             protobuf_nano: "com.google.protobuf.nano:protobuf-javanano:${protobufNanoVersion}",
    220             protobuf_plugin: 'com.google.protobuf:protobuf-gradle-plugin:0.8.5',
    221             protobuf_util: "com.google.protobuf:protobuf-java-util:${protobufVersion}",
    222             lang: "org.apache.commons:commons-lang3:3.5",
    223 
    224             netty: "io.netty:netty-codec-http2:[${nettyVersion}]",
    225             netty_epoll: "io.netty:netty-transport-native-epoll:${nettyVersion}" + epoll_suffix,
    226             netty_proxy_handler: "io.netty:netty-handler-proxy:${nettyVersion}",
    227             netty_tcnative: 'io.netty:netty-tcnative-boringssl-static:2.0.12.Final',
    228 
    229             conscrypt: 'org.conscrypt:conscrypt-openjdk-uber:1.0.1',
    230             re2j: 'com.google.re2j:re2j:1.2',
    231 
    232             // Test dependencies.
    233             junit: 'junit:junit:4.12',
    234             mockito: 'org.mockito:mockito-core:1.9.5',
    235             truth: 'com.google.truth:truth:0.42',
    236             guava_testlib: 'com.google.guava:guava-testlib:20.0',
    237 
    238             // Benchmark dependencies
    239             hdrhistogram: 'org.hdrhistogram:HdrHistogram:2.1.10',
    240             math: 'org.apache.commons:commons-math3:3.6',
    241 
    242             // Jetty ALPN dependencies
    243             jetty_alpn_agent: 'org.mortbay.jetty.alpn:jetty-alpn-agent:2.0.7'
    244         ]
    245     }
    246 
    247     // Define a separate configuration for managing the dependency on Jetty ALPN agent.
    248     configurations {
    249         alpnagent
    250 
    251         compile {
    252             // Detect Maven Enforcer's dependencyConvergence failures. We only
    253             // care for artifacts used as libraries by others.
    254             if (!(project.name in [
    255                 'grpc-benchmarks',
    256                 'grpc-interop-testing',
    257                 'grpc-gae-interop-testing-jdk7',
    258                 'grpc-gae-interop-testing-jdk8',
    259             ])) {
    260                 resolutionStrategy.failOnVersionConflict()
    261             }
    262         }
    263     }
    264 
    265     dependencies {
    266         testCompile libraries.junit,
    267                 libraries.mockito,
    268                 libraries.truth
    269 
    270         // Configuration for modules that use Jetty ALPN agent
    271         alpnagent libraries.jetty_alpn_agent
    272 
    273         jmh 'org.openjdk.jmh:jmh-core:1.19',
    274                 'org.openjdk.jmh:jmh-generator-bytecode:1.19'
    275     }
    276 
    277     signing {
    278         required false
    279         sign configurations.archives
    280     }
    281 
    282     // Disable JavaDoc doclint on Java 8. It's annoying.
    283     if (JavaVersion.current().isJava8Compatible()) {
    284         allprojects {
    285             tasks.withType(Javadoc) {
    286                 options.addStringOption('Xdoclint:none', '-quiet')
    287             }
    288         }
    289     }
    290 
    291     // For jdk10 we must explicitly choose between html4 and html5, otherwise we get a warning
    292     if (JavaVersion.current().isJava10Compatible()) {
    293         allprojects {
    294             tasks.withType(Javadoc) {
    295                 options.addBooleanOption('html4', true)
    296             }
    297         }
    298     }
    299 
    300     checkstyle {
    301         configDir = file("$rootDir/buildscripts")
    302         toolVersion = "6.17"
    303         ignoreFailures = false
    304         if (rootProject.hasProperty("checkstyle.ignoreFailures")) {
    305             ignoreFailures = rootProject.properties["checkstyle.ignoreFailures"].toBoolean()
    306         }
    307     }
    308 
    309     checkstyleMain {
    310         source = fileTree(dir: "src/main", include: "**/*.java")
    311     }
    312 
    313     checkstyleTest {
    314         source = fileTree(dir: "src/test", include: "**/*.java")
    315     }
    316 
    317     // invoke jmh on a single benchmark class like so:
    318     //   ./gradlew -PjmhIncludeSingleClass=StatsTraceContextBenchmark clean :grpc-core:jmh
    319     jmh {
    320         warmupIterations = 10
    321         iterations = 10
    322         fork = 1
    323         // None of our benchmarks need the tests, and we have pseudo-circular
    324         // dependencies that break when including them. (context's testCompile
    325         // depends on core; core's testCompile depends on testing)
    326         includeTests = false
    327         if (project.hasProperty('jmhIncludeSingleClass')) {
    328             include = [
    329                 project.property('jmhIncludeSingleClass')
    330             ]
    331         }
    332     }
    333 
    334     task javadocJar(type: Jar) {
    335         classifier = 'javadoc'
    336         from javadoc
    337     }
    338 
    339     task sourcesJar(type: Jar) {
    340         classifier = 'sources'
    341         from sourceSets.main.allSource
    342     }
    343 
    344     artifacts { archives javadocJar, sourcesJar }
    345 
    346     uploadArchives.repositories.mavenDeployer {
    347         beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
    348         if (rootProject.hasProperty('repositoryDir')) {
    349             repository(url: new File(rootProject.repositoryDir).toURI())
    350         } else {
    351             String stagingUrl
    352             if (rootProject.hasProperty('repositoryId')) {
    353                 stagingUrl = 'https://oss.sonatype.org/service/local/staging/deployByRepositoryId/' +
    354                         rootProject.repositoryId
    355             } else {
    356                 stagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
    357             }
    358             def configureAuth = {
    359                 if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) {
    360                     authentication(userName: rootProject.ossrhUsername, password: rootProject.ossrhPassword)
    361                 }
    362             }
    363             repository(url: stagingUrl, configureAuth)
    364             snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/', configureAuth)
    365         }
    366     }
    367     uploadArchives.onlyIf { !name.contains("grpc-gae-interop-testing") }
    368 
    369     [
    370         install.repositories.mavenInstaller,
    371         uploadArchives.repositories.mavenDeployer,
    372     ]*.pom*.whenConfigured { pom ->
    373         pom.project {
    374             name "$project.group:$project.name"
    375             description project.description
    376             url 'https://github.com/grpc/grpc-java'
    377 
    378             scm {
    379                 connection 'scm:git:https://github.com/grpc/grpc-java.git'
    380                 developerConnection 'scm:git:git (a] github.com:grpc/grpc-java.git'
    381                 url 'https://github.com/grpc/grpc-java'
    382             }
    383 
    384             licenses {
    385                 license {
    386                     name 'Apache 2.0'
    387                     url 'https://opensource.org/licenses/Apache-2.0'
    388                 }
    389             }
    390 
    391             developers {
    392                 developer {
    393                     id "grpc.io"
    394                     name "gRPC Contributors"
    395                     email "grpc-io (a] googlegroups.com"
    396                     url "https://grpc.io/"
    397                     // https://issues.gradle.org/browse/GRADLE-2719
    398                     organization = "gRPC Authors"
    399                     organizationUrl "https://www.google.com"
    400                 }
    401             }
    402         }
    403         if (!(project.name in
    404         [
    405             "grpc-stub",
    406             "grpc-protobuf",
    407             "grpc-protobuf-lite",
    408             "grpc-protobuf-nano"
    409         ])) {
    410             def core = pom.dependencies.find {dep -> dep.artifactId == 'grpc-core'}
    411             if (core != null) {
    412                 // Depend on specific version of grpc-core because internal package is unstable
    413                 core.version = "[" + core.version + "]"
    414             }
    415         }
    416     }
    417     // At a test failure, log the stack trace to the console so that we don't
    418     // have to open the HTML in a browser.
    419     test {
    420         testLogging {
    421             exceptionFormat = 'full'
    422             showExceptions true
    423             showCauses true
    424             showStackTraces true
    425         }
    426         maxHeapSize = '1500m'
    427     }
    428 }
    429 
    430 // Run with: ./gradlew japicmp --continue
    431 def baselineGrpcVersion = '1.6.1'
    432 def publicApiSubprojects = [
    433     // TODO: uncomment after grpc-alts artifact is published.
    434     // ':grpc-alts',
    435     ':grpc-auth',
    436     ':grpc-context',
    437     ':grpc-core',
    438     ':grpc-grpclb',
    439     ':grpc-netty',
    440     ':grpc-okhttp',
    441     ':grpc-protobuf',
    442     ':grpc-protobuf-lite',
    443     ':grpc-protobuf-nano',
    444     ':grpc-stub',
    445     ':grpc-testing',
    446 ]
    447 
    448 publicApiSubprojects.each { name ->
    449     project(":$name") {
    450         apply plugin: 'me.champeau.gradle.japicmp'
    451 
    452         // Get the baseline version's jar for this subproject
    453         File baselineArtifact = null
    454         // Use a detached configuration, otherwise the current version's jar will take precedence
    455         // over the baseline jar.
    456         // A necessary hack, the intuitive thing does NOT work:
    457         // https://discuss.gradle.org/t/is-the-default-configuration-leaking-into-independent-configurations/2088/6
    458         def oldGroup = project.group
    459         try {
    460             project.group = 'virtual_group_for_japicmp'
    461             String depModule = "io.grpc:${project.name}:${baselineGrpcVersion}@jar"
    462             String depJar = "${project.name}-${baselineGrpcVersion}.jar"
    463             Configuration configuration = configurations.detachedConfiguration(
    464                     dependencies.create(depModule)
    465                     )
    466             baselineArtifact = files(configuration.files).filter {
    467                 it.name.equals(depJar)
    468             }.singleFile
    469         } finally {
    470             project.group = oldGroup
    471         }
    472 
    473         // Add a japicmp task that compares the current .jar with baseline .jar
    474         task japicmp(type: me.champeau.gradle.japicmp.JapicmpTask, dependsOn: jar) {
    475             oldClasspath = files(baselineArtifact)
    476             newClasspath = files(jar.archivePath)
    477             onlyBinaryIncompatibleModified = false
    478             // Be quiet about things that did not change
    479             onlyModified = true
    480             // This task should fail if there are incompatible changes
    481             failOnModification = true
    482             ignoreMissingClasses = true
    483             htmlOutputFile = file("$buildDir/reports/japi.html")
    484 
    485             packageExcludes = ['io.grpc.internal']
    486 
    487             // Also break on source incompatible changes, not just binary.
    488             // Eg adding abstract method to public class.
    489             // TODO(zpencer): enable after japicmp-gradle-plugin/pull/14
    490             // breakOnSourceIncompatibility = true
    491 
    492             // Ignore any classes or methods marked @ExperimentalApi
    493             // TODO(zpencer): enable after japicmp-gradle-plugin/pull/15
    494             // annotationExcludes = ['@io.grpc.ExperimentalApi']
    495         }
    496     }
    497 }
    498 
    499 // format checkers
    500 apply plugin: "com.diffplug.gradle.spotless"
    501 apply plugin: 'groovy'
    502 spotless {
    503     groovyGradle {
    504         target '**/*.gradle'
    505         greclipse()
    506         indentWithSpaces()
    507         paddedCell()
    508     }
    509 }
    510