Reputation: 870
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
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