import java.util.jar.JarFile plugins { id "java" id "maven-publish" id "com.github.johnrengelman.shadow" id "com.google.protobuf" id "ru.vyarus.animalsniffer" } description = "gRPC: XDS plugin" evaluationDependsOn(project(':grpc-core').path) sourceSets { thirdparty { java { srcDir "${projectDir}/third_party/zero-allocation-hashing/main/java" } proto { srcDir 'third_party/envoy/src/main/proto' srcDir 'third_party/protoc-gen-validate/src/main/proto' srcDir 'third_party/xds/src/main/proto' srcDir 'third_party/googleapis/src/main/proto' srcDir 'third_party/istio/src/main/proto' } } test { java { srcDir "${projectDir}/third_party/zero-allocation-hashing/test/java" } } } configurations { pomDeps { extendsFrom configurations.thirdpartyRuntimeClasspath, configurations.shadow } } dependencies { thirdpartyCompileOnly libraries.javax.annotation thirdpartyImplementation project(':grpc-protobuf'), project(':grpc-stub'), libraries.opencensus.proto implementation sourceSets.thirdparty.output implementation project(':grpc-stub'), project(':grpc-core'), project(':grpc-services'), project(':grpc-auth'), project(path: ':grpc-alts', configuration: 'shadow'), libraries.gson, libraries.re2j, libraries.auto.value.annotations, libraries.protobuf.java.util def nettyDependency = implementation project(':grpc-netty') testImplementation project(':grpc-rls') testImplementation project(':grpc-core').sourceSets.test.output annotationProcessor libraries.auto.value // At runtime use the epoll included in grpc-netty-shaded compileOnly libraries.netty.transport.epoll testImplementation project(':grpc-testing'), project(':grpc-testing-proto') testImplementation (libraries.netty.transport.epoll) { artifact { classifier = "linux-x86_64" } } testImplementation (libraries.guava.testlib) { exclude group: 'junit', module: 'junit' } shadow configurations.implementation.getDependencies().minus([nettyDependency]) shadow project(path: ':grpc-netty-shaded', configuration: 'shadow') signature libraries.signature.java testRuntimeOnly libraries.netty.tcnative, libraries.netty.tcnative.classes testRuntimeOnly (libraries.netty.tcnative) { artifact { classifier = "linux-x86_64" } } testRuntimeOnly (libraries.netty.tcnative) { artifact { classifier = "linux-aarch_64" } } testRuntimeOnly (libraries.netty.tcnative) { artifact { classifier = "osx-x86_64" } } testRuntimeOnly (libraries.netty.tcnative) { artifact { classifier = "osx-aarch_64" } } testRuntimeOnly (libraries.netty.tcnative) { artifact { classifier = "windows-x86_64" } } } configureProtoCompilation() tasks.named("compileThirdpartyJava").configure { options.errorprone.enabled = false options.compilerArgs += [ // valueOf(int) in RoutingPriority has been deprecated "-Xlint:-deprecation", ] } tasks.named("checkstyleThirdparty").configure { enabled = false } tasks.named("compileJava").configure { it.options.compilerArgs += [ // TODO: remove "-Xlint:-deprecation", // only has AutoValue annotation processor "-Xlint:-processing", ] appendToProperty( it.options.errorprone.excludedPaths, ".*/build/generated/sources/annotationProcessor/java/.*", "|") } tasks.named("jar").configure { archiveClassifier = 'original' from sourceSets.thirdparty.output } tasks.named("javadoc").configure { // Exclusions here should generally also be relocated exclude 'com/github/udpa/**' exclude 'com/github/xds/**' exclude 'com/google/security/**' exclude 'io/envoyproxy/**' // Need to clean up the class structure to reduce how much is exposed exclude 'io/grpc/xds/*LoadBalancer*' exclude 'io/grpc/xds/Bootstrapper.java' exclude 'io/grpc/xds/Envoy*' exclude 'io/grpc/xds/FilterChainMatchingProtocolNegotiators.java' exclude 'io/grpc/xds/TlsContextManager.java' exclude 'io/grpc/xds/XdsAttributes.java' exclude 'io/grpc/xds/XdsInitializationException.java' exclude 'io/grpc/xds/XdsNameResolverProvider.java' exclude 'io/grpc/xds/internal/**' exclude 'io/grpc/xds/Internal*' } def prefixName = 'io.grpc.xds' tasks.named("shadowJar").configure { archiveClassifier = null dependencies { include(project(':grpc-xds')) } // Relocated packages commonly need exclusions in jacocoTestReport and javadoc relocate 'com.github.udpa', "${prefixName}.shaded.com.github.udpa" relocate 'com.github.xds', "${prefixName}.shaded.com.github.xds" relocate 'com.google.api.expr', "${prefixName}.shaded.com.google.api.expr" relocate 'com.google.security', "${prefixName}.shaded.com.google.security" // TODO: missing java_package option in .proto relocate 'envoy.annotations', "${prefixName}.shaded.envoy.annotations" relocate 'io.envoyproxy', "${prefixName}.shaded.io.envoyproxy" relocate 'io.grpc.netty', 'io.grpc.netty.shaded.io.grpc.netty' relocate 'io.netty', 'io.grpc.netty.shaded.io.netty' // TODO: missing java_package option in .proto relocate 'udpa.annotations', "${prefixName}.shaded.udpa.annotations" relocate 'xds.annotations', "${prefixName}.shaded.xds.annotations" exclude "**/*.proto" } def checkPackageLeakage = tasks.register("checkPackageLeakage") { inputs.files(shadowJar).withNormalizer(CompileClasspathNormalizer) outputs.file("${buildDir}/tmp/${name}") // Fake output for UP-TO-DATE checking doLast { def jarEntryPrefixName = prefixName.replaceAll('\\.', '/') shadowJar.outputs.getFiles().each { jar -> def package_leak_detected = false JarFile jf = new JarFile(jar) jf.entries().each { entry -> if (entry.name.endsWith(".class") && !entry.name.startsWith( jarEntryPrefixName)) { package_leak_detected = true println "WARNING: package leaked, may need relocation: " + entry.name } } jf.close() if (package_leak_detected) { throw new TaskExecutionException(shadowJar, new IllegalStateException("Resource leakage detected!")) } } } } tasks.named("test").configure { dependsOn checkPackageLeakage } tasks.named("jacocoTestReport").configure { classDirectories.from = sourceSets.main.output.collect { fileTree(dir: it, exclude: [ // Exclusions here should generally also be relocated '**/com/github/udpa/**', '**/com/github/xds/**', '**/com/google/api/expr/**', '**/com/google/security/**', '**/envoy/annotations/**', '**/io/envoyproxy/**', '**/udpa/annotations/**', '**/xds/annotations/**', ]) } } publishing { publications { maven(MavenPublication) { // We want this to throw an exception if it isn't working def originalJar = artifacts.find { dep -> dep.classifier == 'original'} artifacts.remove(originalJar) pom.withXml { def dependenciesNode = new Node(null, 'dependencies') project.configurations.pomDeps.allDependencies.each { dep -> if (dep.group == null && dep.name == 'unspecified') { // Ignore the thirdparty self-dependency return; } def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) def version = (dep.name == 'grpc-netty-shaded') ? '[' + dep.version + ']' : dep.version dependencyNode.appendNode('version', version) dependencyNode.appendNode('scope', 'compile') } asNode().dependencies[0].replaceNode(dependenciesNode) } } } }