| import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer |
| import com.github.jengelman.gradle.plugins.shadow.transformers.CacheableTransformer |
| import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext |
| import org.gradle.api.file.FileTreeElement |
| import shadow.org.apache.tools.zip.ZipOutputStream |
| import shadow.org.apache.tools.zip.ZipEntry |
| |
| plugins { |
| id "java" |
| id "maven-publish" |
| |
| id "com.github.johnrengelman.shadow" |
| id "ru.vyarus.animalsniffer" |
| } |
| |
| description = "gRPC: Netty Shaded" |
| |
| sourceSets { testShadow {} } |
| |
| dependencies { |
| implementation project(':grpc-netty') |
| runtimeOnly libraries.netty.tcnative, |
| libraries.netty.tcnative.classes |
| runtimeOnly (libraries.netty.tcnative) { |
| artifact { |
| classifier = "linux-x86_64" |
| } |
| } |
| runtimeOnly (libraries.netty.tcnative) { |
| artifact { |
| classifier = "linux-aarch_64" |
| } |
| } |
| runtimeOnly (libraries.netty.tcnative) { |
| artifact { |
| classifier = "osx-x86_64" |
| } |
| } |
| runtimeOnly (libraries.netty.tcnative) { |
| artifact { |
| classifier = "osx-aarch_64" |
| } |
| } |
| runtimeOnly (libraries.netty.tcnative) { |
| artifact { |
| classifier = "windows-x86_64" |
| } |
| } |
| runtimeOnly (libraries.netty.transport.epoll) { |
| artifact { |
| classifier = "linux-x86_64" |
| } |
| } |
| runtimeOnly (libraries.netty.transport.epoll) { |
| artifact { |
| classifier = "linux-aarch_64" |
| } |
| } |
| testShadowImplementation files(shadowJar), |
| project(':grpc-testing-proto'), |
| project(':grpc-testing'), |
| libraries.truth |
| shadow project(':grpc-netty').configurations.runtimeClasspath.allDependencies.matching { |
| it.group != 'io.netty' |
| } |
| signature libraries.signature.java |
| signature libraries.signature.android |
| } |
| |
| tasks.named("jar").configure { |
| // Must use a different archiveClassifier to avoid conflicting with shadowJar |
| archiveClassifier = 'original' |
| } |
| |
| tasks.named("shadowJar").configure { |
| archiveClassifier = null |
| dependencies { |
| include(project(':grpc-netty')) |
| include(dependency('io.netty:')) |
| } |
| exclude 'META-INF/maven/**' |
| relocate 'io.grpc.netty', 'io.grpc.netty.shaded.io.grpc.netty' |
| relocate 'io.netty', 'io.grpc.netty.shaded.io.netty' |
| // We have to be careful with these replacements as they must not match any |
| // string in NativeLibraryLoader, else they cause corruption. Note that |
| // this includes concatenation of string literals and constants. |
| relocate 'META-INF/native/libnetty', 'META-INF/native/libio_grpc_netty_shaded_netty' |
| relocate 'META-INF/native/netty', 'META-INF/native/io_grpc_netty_shaded_netty' |
| transform(NettyResourceTransformer.class) |
| mergeServiceFiles() |
| } |
| |
| publishing { |
| publications { |
| maven(MavenPublication) { |
| project.shadow.component(it) |
| |
| // Empty jars are not published via withJavadocJar() and withSourcesJar() |
| artifact javadocJar |
| artifact sourcesJar |
| |
| // Avoid confusing error message "class file for |
| // io.grpc.internal.AbstractServerImplBuilder not found" |
| // (https://github.com/grpc/grpc-java/issues/5881). This can be |
| // removed after https://github.com/grpc/grpc-java/issues/7211 is |
| // resolved. |
| pom.withXml { |
| asNode().dependencies.'*'.findAll() { dep -> |
| dep.artifactId.text() == 'grpc-core' |
| }.each() { core -> |
| core.scope*.value = "compile" |
| } |
| } |
| } |
| } |
| } |
| |
| tasks.register("testShadow", Test) { |
| testClassesDirs = sourceSets.testShadow.output.classesDirs |
| classpath = sourceSets.testShadow.runtimeClasspath |
| } |
| tasks.named("compileTestShadowJava").configure { |
| options.compilerArgs = compileTestJava.options.compilerArgs |
| options.encoding = compileTestJava.options.encoding |
| } |
| |
| tasks.named("test").configure { |
| dependsOn tasks.named("testShadow") |
| } |
| |
| /** |
| * A Transformer which updates the Netty JAR META-INF/ resources to accurately |
| * reference shaded class names. |
| */ |
| @CacheableTransformer |
| class NettyResourceTransformer implements Transformer { |
| |
| // A map of resource file paths to be modified |
| private Map<String, String> resources = [:] |
| |
| @Override |
| boolean canTransformResource(FileTreeElement fileTreeElement) { |
| fileTreeElement.name.startsWith("META-INF/native-image/io.netty") |
| } |
| |
| @Override |
| void transform(TransformerContext context) { |
| String updatedPath = context.path.replace("io.netty", "io.grpc.netty.shaded.io.netty") |
| String updatedContent = context.is.getText().replace("io.netty", "io.grpc.netty.shaded.io.netty") |
| resources.put(updatedPath, updatedContent) |
| } |
| |
| @Override |
| boolean hasTransformedResource() { |
| resources.size() > 0 |
| } |
| |
| @Override |
| void modifyOutputStream(ZipOutputStream outputStream, boolean preserveFileTimestamps) { |
| for (resourceEntry in resources) { |
| ZipEntry entry = new ZipEntry(resourceEntry.key) |
| entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time) |
| |
| outputStream.putNextEntry(entry) |
| outputStream.write(resourceEntry.value.getBytes()) |
| outputStream.closeEntry() |
| } |
| } |
| } |