Hmmmmm
Hmmmmm

Reputation: 870

Does grpc-core work when embedded in a shaded jar?

TL;DR

The grpc-core jar file doesn't work when embedded in a shaded jar but does work when placed on the classpath as a separate jar file. I can't tell if the issue is with grpc-core or grpc-netty (or grpc-netty-shaded) which seems to depend on grpc-core, but when grpc-core is embedded in my shaded jar, I get a java.nio.channels.UnsupportedAddressTypeException exception.

Longer Explanation

Until recently my Java web application (that deploys as a .war file) did not make use of shaded jar files. That is, in the WEB-INF folder contained all the jar files individually laid out. I recently made a change to use a shaded jar and everything works fine except for an integration that makes use of grpc-netty-shaded. I have tried using different versions of the grpc-* libraries and using both the shaded and unshaded version of grpc-netty, but neither of those work when I create a shaded jar.

However, if I produce a shaded jar and place the grpc-core library separately (as a sibling to the shaded jar in the WEB-INF folder) then everything works. I should also say that it doesn't matter if I run the application from within Tomcat or deploy it from the command line, the result is the same. I have also tried switching the JRE I am using but that made no difference.

Here is the exception I get:

Exception in thread "main" io.grpc.StatusRuntimeException: UNKNOWN
    at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:271)
    at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:252)
    at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:165)
    at com.ibm.crypto.grep11.grpc.CryptoGrpc$CryptoBlockingStub.generateKey(CryptoGrpc.java:2964)
    at ibm.TestHpcsGrep11.main(TestHpcsGrep11.java:77)
Caused by: java.nio.channels.UnsupportedAddressTypeException
    at sun.nio.ch.Net.checkAddress(Unknown Source)
    at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
    at io.grpc.netty.shaded.io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:91)
    at io.grpc.netty.shaded.io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:88)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.grpc.netty.shaded.io.netty.util.internal.SocketUtils.connect(SocketUtils.java:88)
    at io.grpc.netty.shaded.io.netty.channel.socket.nio.NioSocketChannel.doConnect(NioSocketChannel.java:315)
    at io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.connect(AbstractNioChannel.java:248)
    at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.connect(DefaultChannelPipeline.java:1342)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:548)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:533)
    at io.grpc.netty.shaded.io.netty.channel.ChannelDuplexHandler.connect(ChannelDuplexHandler.java:54)
    at io.grpc.netty.shaded.io.grpc.netty.WriteBufferingAndExceptionHandler.connect(WriteBufferingAndExceptionHandler.java:157)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:548)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.access$1000(AbstractChannelHandlerContext.java:61)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext$9.run(AbstractChannelHandlerContext.java:538)
    at io.grpc.netty.shaded.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
    at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)
    at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
    at io.grpc.netty.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.grpc.netty.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Unknown Source)

This is the project I am integrating with. While the project makes use of version 1.44.0 of the grpc libraries, I have tried it with 1.44.0, 1.47.0, and 1.48.1 and always get the same result.

Here is the Maven plugin configuration I am using to produce the shaded jar:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals><goal>shade</goal></goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <artifactSet>
                    <excludes>
                        <exclude>junit:junit</exclude>
                        <exclude>org.testng:testng</exclude>
                        <exclude>javax.servlet:servlet-api</exclude>
                    </excludes>
                </artifactSet>
            </configuration>
        </execution>
    </executions>
</plugin>

Upvotes: 4

Views: 1985

Answers (1)

Patrick Klampfl
Patrick Klampfl

Reputation: 66

I did spend hours resolving the same issue, but finally found the root cause.

When running your mvn package command, you most likely get a warning similar to the following:

[WARNING] grpc-core-1.48.1.jar, grpc-netty-shaded-1.48.1.jar define 1 overlapping resource: 
[WARNING]   - META-INF/services/io.grpc.NameResolverProvider

those 2 files need to be merged (otherwise maven won't take any of them).

this can be done by adding the following to your pom.xml within your maven shade plugin <configuration>

<transformers>
    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>

this will merge your duplicate files and also respect potential relocations from the shade plugin.

also see

Upvotes: 4

Related Questions