grpc核心在嵌入阴影罐子中时工作吗



TL;DR

grpc核心jar文件在嵌入到着色jar中时不起作用,但在作为单独的jar文件放置在类路径中时起作用。我不知道问题是grpc核心还是grpc netty(或grpc nettty-shaded(,这似乎取决于grpc核心,但当grpc核心嵌入到我的shaded jar中时,我会得到一个java.nio.channes.UnsupportedAddressTypeException异常。

更长的解释

直到最近,我的Java web应用程序(部署为.war文件(还没有使用着色jar文件。也就是说,在WEB-INF文件夹中,包含单独布局的所有jar文件。我最近做了一个更改,使用了着色jar,除了使用grpc netty着色的集成外,一切都很好。我尝试过使用不同版本的grpc-*库,并同时使用grpc-netty的着色和非着色版本,但当我创建着色jar时,这两种方法都不起作用。

但是,如果我生成一个着色的jar,并且将grpc核心库单独放置(作为WEB-INF文件夹中着色jar的同级库(,那么一切都可以工作。我还应该说,无论是从Tomcat中运行应用程序还是从命令行部署应用程序,结果都是一样的。我也尝试过切换我正在使用的JRE,但没有什么不同。

这是我得到的例外:

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)

这就是我正在整合的项目。虽然该项目使用了grpc库的1.44.0版本,但我尝试过1.44.0、1.47.0和1.48.1版本,总是得到相同的结果。

以下是我用来生成着色jar的Maven插件配置:

<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>

我确实花了几个小时解决了同样的问题,但最终找到了根本原因。

当运行mvn package命令时,您很可能会收到类似以下的警告:

[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

这两个文件需要合并(否则maven将不会接受它们中的任何一个(。

这可以通过在您的maven shade插件<configuration>中向pom.xml添加以下内容来完成

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

这将合并您的重复文件,并尊重潜在的重新定位从阴影插件。

另请参见

  • https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#ServicesResourceTransformer
  • Maven Shade-更改文件名并替换文本

最新更新