Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify netty-shaded resources to reference shaded class names #8258

Merged
merged 3 commits into from Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 55 additions & 0 deletions netty/shaded/build.gradle
@@ -1,3 +1,19 @@
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
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


buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:6.1.0"
}
}

plugins {
id "java"
id "maven-publish"
Expand Down Expand Up @@ -41,6 +57,7 @@ shadowJar {
// 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()
}

Expand Down Expand Up @@ -73,3 +90,41 @@ compileTestShadowJava.options.compilerArgs = compileTestJava.options.compilerArg
compileTestShadowJava.options.encoding = compileTestJava.options.encoding

test.dependsOn testShadow

/**
* A Transformer which updates the Netty JAR META-INF/ resources to accurately
* reference shaded class names.
*/
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 updatedContent = context.is.getText().replace("io.netty", "io.grpc.netty.shaded.io.netty")
resources.put(context.path, 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()
}
}
}
Expand Up @@ -39,6 +39,11 @@
import io.grpc.testing.protobuf.SimpleServiceGrpc;
import io.grpc.testing.protobuf.SimpleServiceGrpc.SimpleServiceBlockingStub;
import io.grpc.testing.protobuf.SimpleServiceGrpc.SimpleServiceImplBase;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Test;
Expand Down Expand Up @@ -69,6 +74,19 @@ public void noNormalNetty() throws Exception {
Class.forName("io.grpc.netty.NettyServerBuilder");
}

/** Verify that resources under META-INF/native-image reference shaded class names. */
@Test
public void nettyResourcesUpdated() throws IOException {
InputStream inputStream = NettyChannelBuilder.class.getClassLoader()
.getResourceAsStream("META-INF/native-image/io.netty/transport/reflection-config.json");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really ought to rename the files as well (the "io.netty" folder), to avoid them colliding with Netty's files. But we can do that as a follow-up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, will do.

assertThat(inputStream).isNotNull();

Scanner s = new Scanner(inputStream, StandardCharsets.UTF_8.name()).useDelimiter("\\A");
String reflectionConfig = s.hasNext() ? s.next() : "";

assertThat(reflectionConfig).contains("io.grpc.netty.shaded.io.netty");
}

@Test
public void serviceLoaderFindsNetty() throws Exception {
assertThat(Grpc.newServerBuilderForPort(0, InsecureServerCredentials.create()))
Expand Down