From 8cf0196548b081122b79f4c447058b3a7d34513b Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Thu, 9 Jan 2020 15:20:41 -0800 Subject: [PATCH] Add Cronet to main build Building now requires an Android SDK unless you specify -PskipAndroid=true --- .travis.yml | 1 + COMPILING.md | 5 + build.gradle | 32 +++-- buildscripts/kokoro/android.sh | 8 +- buildscripts/kokoro/gae-interop.sh | 2 +- buildscripts/kokoro/linux_artifacts.sh | 1 - buildscripts/kokoro/unix.sh | 1 + buildscripts/kokoro/windows32.bat | 2 +- buildscripts/kokoro/windows64.bat | 2 +- cronet/build.gradle | 117 ++---------------- cronet/settings.gradle | 1 - .../io/grpc/cronet/CronetClientStream.java | 4 +- .../grpc/cronet/CronetClientStreamTest.java | 5 +- settings.gradle | 21 ++++ 14 files changed, 75 insertions(+), 127 deletions(-) delete mode 100644 cronet/settings.gradle diff --git a/.travis.yml b/.travis.yml index c80ca705347..0dc75902eba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ before_install: - echo "checkstyle.ignoreFailures=false" >> $HOME/.gradle/gradle.properties - echo "failOnWarnings=true" >> $HOME/.gradle/gradle.properties - echo "errorProne=true" >> $HOME/.gradle/gradle.properties + - echo "skipAndroid=true" >> $HOME/.gradle/gradle.properties install: - ./gradlew assemble syncGeneratedSources publishToMavenLocal diff --git a/COMPILING.md b/COMPILING.md index 486fb7b226a..a7d9c4e11d2 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -11,6 +11,11 @@ developers don't have C compilers installed and don't need to run or modify the codegen, the build can skip it. To skip, create the file `/gradle.properties` and add `skipCodegen=true`. +Some parts of grpc-java depend on Android. Since many Java developers don't have +the Android SDK installed and don't need to run or modify the Android +components, the build can skip it. To skip, create the file +`/gradle.properties` and add `skipAndroid=true`. + Then, to build, run: ``` $ ./gradlew build diff --git a/build.gradle b/build.gradle index 38f27977b66..320441d405a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,5 @@ plugins { + id "com.android.library" apply false // Necessary for Android plugin to find its classes id "com.google.osdetector" apply false id "me.champeau.gradle.japicmp" apply false id "net.ltgt.errorprone" apply false @@ -114,6 +115,8 @@ subprojects { android_annotations: "com.google.android:annotations:4.1.1.4", animalsniffer_annotations: "org.codehaus.mojo:animal-sniffer-annotations:1.18", errorprone: "com.google.errorprone:error_prone_annotations:2.3.4", + cronet_api: 'org.chromium.net:cronet-api:76.3809.111', + cronet_embedded: 'org.chromium.net:cronet-embedded:66.3359.158', gson: "com.google.code.gson:gson:2.8.6", guava: "com.google.guava:guava:${guavaVersion}", hpack: 'com.twitter:hpack:0.10.1', @@ -154,6 +157,7 @@ subprojects { mockito: 'org.mockito:mockito-core:2.28.2', truth: 'com.google.truth:truth:1.0', guava_testlib: "com.google.guava:guava-testlib:${guavaVersion}", + robolectric: "org.robolectric:robolectric:3.5.1", // Benchmark dependencies hdrhistogram: 'org.hdrhistogram:HdrHistogram:2.1.10', @@ -208,6 +212,22 @@ subprojects { } } + if (rootProject.properties.get('errorProne', true)) { + dependencies { + errorprone 'com.google.errorprone:error_prone_core:2.3.4' + errorproneJavac 'com.google.errorprone:javac:9+181-r4173-1' + } + } else { + // Disable Error Prone + allprojects { + afterEvaluate { project -> + project.tasks.withType(JavaCompile) { + options.errorprone.enabled = false + } + } + } + } + plugins.withId("java") { sourceCompatibility = 1.7 targetCompatibility = 1.7 @@ -263,20 +283,8 @@ subprojects { if (rootProject.properties.get('errorProne', true)) { dependencies { - errorprone 'com.google.errorprone:error_prone_core:2.3.4' - errorproneJavac 'com.google.errorprone:javac:9+181-r4173-1' - annotationProcessor 'com.google.guava:guava-beta-checker:1.0' } - } else { - // Disable Error Prone - allprojects { - afterEvaluate { project -> - project.tasks.withType(JavaCompile) { - options.errorprone.enabled = false - } - } - } } compileJava { diff --git a/buildscripts/kokoro/android.sh b/buildscripts/kokoro/android.sh index 358db09c46b..909c446b59e 100755 --- a/buildscripts/kokoro/android.sh +++ b/buildscripts/kokoro/android.sh @@ -10,12 +10,18 @@ BASE_DIR="$(pwd)" cd "$BASE_DIR/github/grpc-java" -export GRADLE_OPTS=-Xmx512m export LDFLAGS=-L/tmp/protobuf/lib export CXXFLAGS=-I/tmp/protobuf/include export LD_LIBRARY_PATH=/tmp/protobuf/lib export OS_NAME=$(uname) +cat <> gradle.properties +# defaults to -Xmx512m -XX:MaxMetaspaceSize=256m +# https://docs.gradle.org/current/userguide/build_environment.html#sec:configuring_jvm_memory +# Increased due to java.lang.OutOfMemoryError: Metaspace failures +org.gradle.jvmargs=-Xmx512m -XX:MaxMetaspaceSize=512m +EOF + echo y | ${ANDROID_HOME}/tools/bin/sdkmanager "build-tools;28.0.3" # Proto deps diff --git a/buildscripts/kokoro/gae-interop.sh b/buildscripts/kokoro/gae-interop.sh index cbdff2da59b..b3973031d85 100755 --- a/buildscripts/kokoro/gae-interop.sh +++ b/buildscripts/kokoro/gae-interop.sh @@ -28,7 +28,7 @@ cd "$GRPC_JAVA_DIR" ## ## Deploy the dummy 'default' version of the service ## -GRADLE_FLAGS="--stacktrace -DgaeStopPreviousVersion=false -PskipCodegen=true" +GRADLE_FLAGS="--stacktrace -DgaeStopPreviousVersion=false -PskipCodegen=true -PskipAndroid=true" # Deploy the dummy 'default' version. We only require that it exists when cleanup() is called. # It ok if we race with another run and fail here, because the end result is idempotent. diff --git a/buildscripts/kokoro/linux_artifacts.sh b/buildscripts/kokoro/linux_artifacts.sh index cdf360762fb..ed448ffa8c8 100755 --- a/buildscripts/kokoro/linux_artifacts.sh +++ b/buildscripts/kokoro/linux_artifacts.sh @@ -24,7 +24,6 @@ popd pushd "$GRPC_JAVA_DIR/cronet" ../gradlew publish \ - --include-build "$GRPC_JAVA_DIR" \ -Dorg.gradle.parallel=false \ -PskipCodegen=true \ -PrepositoryDir="$LOCAL_MVN_TEMP" diff --git a/buildscripts/kokoro/unix.sh b/buildscripts/kokoro/unix.sh index c64bc7e222c..343b1ae2c09 100755 --- a/buildscripts/kokoro/unix.sh +++ b/buildscripts/kokoro/unix.sh @@ -36,6 +36,7 @@ GRADLE_FLAGS+=" -PtargetArch=$ARCH" GRADLE_FLAGS+=" -Pcheckstyle.ignoreFailures=false" GRADLE_FLAGS+=" -PfailOnWarnings=true" GRADLE_FLAGS+=" -PerrorProne=true" +GRADLE_FLAGS+=" -PskipAndroid=true" GRADLE_FLAGS+=" -Dorg.gradle.parallel=true" export GRADLE_OPTS="-Xmx512m" diff --git a/buildscripts/kokoro/windows32.bat b/buildscripts/kokoro/windows32.bat index ca4549dc00e..5a87b779da3 100644 --- a/buildscripts/kokoro/windows32.bat +++ b/buildscripts/kokoro/windows32.bat @@ -28,7 +28,7 @@ SET TARGET_ARCH=x86_32 SET FAIL_ON_WARNINGS=true SET VC_PROTOBUF_LIBS=%ESCWORKSPACE%\\grpc-java-helper32\\protobuf-%PROTOBUF_VER%\\cmake\\build\\Release SET VC_PROTOBUF_INCLUDE=%ESCWORKSPACE%\\grpc-java-helper32\\protobuf-%PROTOBUF_VER%\\cmake\\build\\include -SET GRADLE_FLAGS=-PtargetArch=%TARGET_ARCH% -PfailOnWarnings=%FAIL_ON_WARNINGS% -PvcProtobufLibs=%VC_PROTOBUF_LIBS% -PvcProtobufInclude=%VC_PROTOBUF_INCLUDE% +SET GRADLE_FLAGS=-PtargetArch=%TARGET_ARCH% -PfailOnWarnings=%FAIL_ON_WARNINGS% -PvcProtobufLibs=%VC_PROTOBUF_LIBS% -PvcProtobufInclude=%VC_PROTOBUF_INCLUDE% -PskipAndroid=true cmd.exe /C "%WORKSPACE%\gradlew.bat %GRADLE_FLAGS% build" set GRADLEEXIT=%ERRORLEVEL% diff --git a/buildscripts/kokoro/windows64.bat b/buildscripts/kokoro/windows64.bat index ae021a7ce37..edcb421fe7d 100644 --- a/buildscripts/kokoro/windows64.bat +++ b/buildscripts/kokoro/windows64.bat @@ -27,7 +27,7 @@ SET TARGET_ARCH=x86_64 SET FAIL_ON_WARNINGS=true SET VC_PROTOBUF_LIBS=%ESCWORKSPACE%\\grpc-java-helper64\\protobuf-%PROTOBUF_VER%\\cmake\\build\\Release SET VC_PROTOBUF_INCLUDE=%ESCWORKSPACE%\\grpc-java-helper64\\protobuf-%PROTOBUF_VER%\\cmake\\build\\include -SET GRADLE_FLAGS=-PtargetArch=%TARGET_ARCH% -PfailOnWarnings=%FAIL_ON_WARNINGS% -PvcProtobufLibs=%VC_PROTOBUF_LIBS% -PvcProtobufInclude=%VC_PROTOBUF_INCLUDE% +SET GRADLE_FLAGS=-PtargetArch=%TARGET_ARCH% -PfailOnWarnings=%FAIL_ON_WARNINGS% -PvcProtobufLibs=%VC_PROTOBUF_LIBS% -PvcProtobufInclude=%VC_PROTOBUF_INCLUDE% -PskipAndroid=true @rem make sure no daemons have any files open cmd.exe /C "%WORKSPACE%\gradlew.bat --stop" diff --git a/cronet/build.gradle b/cronet/build.gradle index 4130d3addc4..aac89f07614 100644 --- a/cronet/build.gradle +++ b/cronet/build.gradle @@ -1,33 +1,15 @@ -apply plugin: 'com.android.library' +plugins { + id "maven-publish" -group = "io.grpc" -version = "1.27.0-SNAPSHOT" // CURRENT_GRPC_VERSION -description = "gRPC: Cronet Android" - -buildscript { - repositories { - google() - jcenter() - mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } - } - dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' - classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.8.1' - classpath 'digital.wup:android-maven-publish:3.6.2' - } + id "com.android.library" + id "digital.wup.android-maven-publish" } -apply plugin: "maven-publish" -apply plugin: "net.ltgt.errorprone" -apply plugin: "digital.wup.android-maven-publish" -apply plugin: "signing" +description = "gRPC: Cronet Android" repositories { google() jcenter() - mavenCentral() - mavenLocal() } android { @@ -51,18 +33,15 @@ android { } dependencies { - errorprone 'com.google.errorprone:error_prone_core:2.3.4' - errorproneJavac 'com.google.errorprone:javac:9+181-r4173-1' + implementation project(':grpc-core') + testImplementation project(':grpc-testing') - implementation 'io.grpc:grpc-core:1.27.0-SNAPSHOT' // CURRENT_GRPC_VERSION - testImplementation 'io.grpc:grpc-testing:1.27.0-SNAPSHOT' // CURRENT_GRPC_VERSION + implementation libraries.cronet_api + testImplementation libraries.cronet_embedded - implementation 'org.chromium.net:cronet-api:76.3809.111' - testImplementation 'org.chromium.net:cronet-embedded:66.3359.158' - - testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.28.2' - testImplementation "org.robolectric:robolectric:3.5.1" + testImplementation libraries.junit + testImplementation libraries.mockito + testImplementation libraries.robolectric } task javadocs(type: Javadoc) { @@ -94,81 +73,11 @@ task sourcesJar(type: Jar) { publishing { publications { - maven(MavenPublication) { + maven { from components.android artifact javadocJar artifact sourcesJar - - pom { - name = project.group + ":" + project.name - url = 'https://github.com/grpc/grpc-java' - afterEvaluate { - // description is not available until evaluated. - description = project.description - } - - scm { - connection = 'scm:git:https://github.com/grpc/grpc-java.git' - developerConnection = 'scm:git:git@github.com:grpc/grpc-java.git' - url = 'https://github.com/grpc/grpc-java' - } - - licenses { - license { - name = 'Apache 2.0' - url = 'https://opensource.org/licenses/Apache-2.0' - } - } - - developers { - developer { - id = "grpc.io" - name = "gRPC Contributors" - email = "grpc-io@googlegroups.com" - url = "https://grpc.io/" - organization = "gRPC Authors" - organizationUrl = "https://www.google.com" - } - } - - withXml { - asNode().dependencies.'*'.findAll() { dep -> - dep.artifactId.text() in ['grpc-api', 'grpc-core'] - }.each() { core -> - core.version*.value = "[" + core.version.text() + "]" - } - } - } - } - } - repositories { - maven { - if (rootProject.hasProperty('repositoryDir')) { - url = new File(rootProject.repositoryDir).toURI() - } else { - String stagingUrl - if (rootProject.hasProperty('repositoryId')) { - stagingUrl = 'https://oss.sonatype.org/service/local/staging/deployByRepositoryId/' + - rootProject.repositoryId - } else { - stagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' - } - credentials { - if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) { - username = rootProject.ossrhUsername - password = rootProject.ossrhPassword - } - } - def releaseUrl = stagingUrl - def snapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots/' - url = version.endsWith('SNAPSHOT') ? snapshotUrl : releaseUrl - } } } } - -signing { - required false - sign publishing.publications.maven -} diff --git a/cronet/settings.gradle b/cronet/settings.gradle deleted file mode 100644 index ca2b16c9c76..00000000000 --- a/cronet/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'grpc-cronet' diff --git a/cronet/src/main/java/io/grpc/cronet/CronetClientStream.java b/cronet/src/main/java/io/grpc/cronet/CronetClientStream.java index 721432f8342..99c545459fa 100644 --- a/cronet/src/main/java/io/grpc/cronet/CronetClientStream.java +++ b/cronet/src/main/java/io/grpc/cronet/CronetClientStream.java @@ -47,10 +47,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.concurrent.Executor; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; @@ -258,7 +256,7 @@ public void cancel(Status reason) { class TransportState extends Http2ClientStreamTransportState { private final Object lock; @GuardedBy("lock") - private Queue pendingData = new LinkedList(); + private Collection pendingData = new ArrayList(); @GuardedBy("lock") private boolean streamReady; @GuardedBy("lock") diff --git a/cronet/src/test/java/io/grpc/cronet/CronetClientStreamTest.java b/cronet/src/test/java/io/grpc/cronet/CronetClientStreamTest.java index 6ff9d1e92cf..34a8b601dbe 100644 --- a/cronet/src/test/java/io/grpc/cronet/CronetClientStreamTest.java +++ b/cronet/src/test/java/io/grpc/cronet/CronetClientStreamTest.java @@ -257,7 +257,7 @@ public void read() { callback.onReadCompleted( cronetStream, info, - (ByteBuffer) createMessageFrame(new String("response1").getBytes(Charset.forName("UTF-8"))), + createMessageFrame(new String("response1").getBytes(Charset.forName("UTF-8"))), false); // Haven't request any message, so no callback is called here. verify(clientListener, times(0)).messagesAvailable(isA(MessageProducer.class)); @@ -308,7 +308,7 @@ public void streamSucceeded() { callback.onReadCompleted( cronetStream, info, - (ByteBuffer) createMessageFrame(new String("response").getBytes(Charset.forName("UTF-8"))), + createMessageFrame(new String("response").getBytes(Charset.forName("UTF-8"))), false); verify(clientListener, times(1)).messagesAvailable(isA(MessageProducer.class)); verify(cronetStream, times(2)).read(isA(ByteBuffer.class)); @@ -573,6 +573,7 @@ public void reportTrailersWhenTrailersReceivedAfterReadClosed() { assertEquals(Status.UNAUTHENTICATED.getCode(), status.getCode()); } + @SuppressWarnings("deprecation") @Test public void addCronetRequestAnnotation_deprecated() { Object annotation = new Object(); diff --git a/settings.gradle b/settings.gradle index 3f9a7e6ef13..0ce56b202c9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,14 +1,27 @@ pluginManagement { plugins { + id "com.android.library" version "3.3.0" id "com.github.johnrengelman.shadow" version "2.0.4" id "com.github.kt3k.coveralls" version "2.0.1" id "com.google.osdetector" version "1.4.0" id "com.google.protobuf" version "0.8.8" + id "digital.wup.android-maven-publish" version "3.6.2" id "me.champeau.gradle.japicmp" version "0.2.5" id "me.champeau.gradle.jmh" version "0.4.5" id "net.ltgt.errorprone" version "0.8.1" id "ru.vyarus.animalsniffer" version "1.5.0" } + resolutionStrategy { + eachPlugin { + if (target.id.namespace == "com.android") { + useModule("com.android.tools.build:gradle:${target.version}") + } + } + } + repositories { + gradlePluginPortal() + google() + } } rootProject.name = "grpc" @@ -62,3 +75,11 @@ if (settings.hasProperty('skipCodegen') && skipCodegen.toBoolean()) { include ":grpc-compiler" project(':grpc-compiler').projectDir = "$rootDir/compiler" as File } + +if (settings.hasProperty('skipAndroid') && skipAndroid.toBoolean()) { + println ' * Skipping the build of Android projects because skipAndroid=true' +} else { + println '*** Android SDK is required. To avoid building Android projects, set -PskipAndroid=true' + include ":grpc-cronet" + project(':grpc-cronet').projectDir = "$rootDir/cronet" as File +}