RPi/PC运行Java程序报netty_tcnative库加载失败问题咨询
问题描述
在RPi 3B+(树莓派3B+)上运行Java程序时抛出Netty TCNative库加载失败报错,此前已尝试过同类问题的所有公开修复方案,包括切换Java 11、将32位操作系统替换为64位版本、引入最新版Netty原生依赖,均未生效。执行mvn clean package打包时,日志明确显示Linux aarch64架构的Netty库已被打入Jar包,但始终无法定位netty_tcnative_linux_aarch64_fedora库加载失败的原因。
报错信息
java.lang.IllegalArgumentException: Failed to load any of the given libraries: [netty_tcnative_linux_aarch_64,netty_tcnative_linux_aarch_64_fedora,netty_tcnative_aarch_64,netty_tcnative] at io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryLoader.loadFirstAvailable(NativeLibraryLoader.java:107) at io.grpc.netty.shaded.io.netty.handler.ssl.OpenSsl.loadTcNative(OpenSsl.java:705) at io.grpc.netty.shaded.io.netty.handler.ssl.OpenSsl.<clinit>(OpenSsl.java:146) at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:230) at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:146) at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:95) at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilderSDefaultProtocolNegotiator.newNegotiator(NettyChannelBuilder.java:628) at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.buildTransportFactory(NettyChannelBuilder.java:530) at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilderSNettyChannelTransportFactoryBuilder.buildclientTransportFactory(NettyChannelBuilder.java:188) at io.grpc.internal.ManagedChannelImplBuilder.build(ManagedChannelImplBuilder.java:626) at io.grpc.internal.AbstractManagedChannelImplBuilder.build(AbstractManagedChannelImplBuilder.java:297) at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel(InstantiatingGrpcChannelProvider.java:388) at com.google.api.gax.grpc.ChannelPool.<init>(ChannelPool.java:105) at com.google.api.gax.grpc.ChannelPool.create(ChannelPool.java:83) at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel(InstantiatingGrpcChannelProvider.java:236) at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel(InstantiatingGrpcChannelProvider.java:230) at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:201)
当前Maven依赖配置
<dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative</artifactId> <version>2.0.52.Final</version> <classifier>linux-aarch_64-fedora</classifier> <scope>runtime</scope> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> <version>2.0.52.Final</version> <classifier>linux-aarch_64</classifier> <scope>runtime</scope> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-handler</artifactId> <version>4.1.77.Final</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.47.0</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.77.Final</version> </dependency>
打包验证日志
[INFO] Including io.netty:netty-tcnative:jar:linux-aarch_64-fedora:2.0.52.Final in the shaded jar. [INFO] Including io.netty:netty-tcnative-classes:jar:2.0.52.Final in the shaded jar. [INFO] Including io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64:2.0.52.Final in the shaded jar. [INFO] Including io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64:2.0.52.Final in the shaded jar. [INFO] Including io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64:2.0.52.Final in the shaded jar. [INFO] Including io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64:2.0.52.Final in the shaded jar. [INFO] Including io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64:2.0.52.Final in the shaded jar.
补充说明
- 此前调试时曾接近在树莓派上调通程序,当时出现报错提示需要切换至Java 8,因切换Java 8的相关命令执行失败,更换为Linux x86-64发行版运行程序后,复现了完全相同的库加载报错。依赖确认已正确引入但库始终无法加载,需要树莓派安装Java 8的可行方法,以及该问题的修复方案。
- 存在异常现象:在aarch64架构的Mac设备上通过命令行运行该程序时,会抛出完全相同的报错提示,但程序仍可正常运行,无法解释该现象。
根因分析与修复方案
核心问题
你使用的grpc-netty-shaded包内部已经重打包了私有版本的Netty,和你在POM中单独引入的外部Netty、TCNative依赖版本路径不匹配,shaded的gRPC不会加载你外部打入的Netty原生库,这是依赖明明进了Jar包但依然加载失败的根本原因。另外你手动为TCNative依赖指定了架构classifier,反而会导致其他匹配逻辑失效。
修复步骤
- 移除POM中所有单独引入的
netty-tcnative(带fedora classifier的那个)、netty-handler、netty-all依赖,不要手动指定外部Netty版本,避免和gRPC Shaded包内部的Netty发生路径冲突。 - 引入和gRPC 1.47.0版本匹配的TCNative依赖,不要加任何架构classifier:
2.0.46.Final及以上版本的<dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> <version>2.0.52.Final</version> <scope>runtime</scope> </dependency>netty-tcnative-boringssl-static已经内置了全平台原生库,手动指定classifier反而会导致依赖残缺。 - 如果以上调整后依然报错,直接在程序启动时添加JVM参数,强制关闭OpenSSL原生库加载,回退到JDK内置SSL实现,绕开整个TCNative加载逻辑:
该方案在树莓派场景下性能损失几乎无法感知,可以100%解决此类加载报错。-Dio.grpc.netty.shaded.io.netty.handler.ssl.openssl=false
额外问题解答
- 树莓派安装Java 8方法:如果使用官方Debian系树莓派系统,直接执行以下命令即可:
执行后在弹出的选项中选择Java 8对应的序号,即可完成默认版本切换。sudo apt update sudo apt install openjdk-8-jdk -y # 切换系统默认Java版本 sudo update-alternatives --config java sudo update-alternatives --config javac - Mac设备上报错但程序正常运行的原因:Netty加载原生库时会按顺序尝试所有可能的库名,单个库加载失败时会打印错误日志,但只要最终能回退到JDK内置的SSL实现,程序就不会中断。这个报错仅代表硬件加速的原生SSL库没有加载成功,自动降级到了兼容实现,不影响核心功能运行。
内容的提问来源于stack exchange,提问作者willbill
相关产品推荐
相关产品推荐

