我尝试在 RPi 3B+ 上运行 Java 程序,但是当我运行它时,出现以下错误。我尝试了无法加载任何给定库:[netty-tcnative-linux-x86_64,netty-tcnative]中的所有修复,但没有一个起作用。我尝试使用 Java 11,使用 64 位操作系统而不是 32 位操作系统,并添加本机 netty 依赖项(使用最新版本)。我真的不确定为什么无法加载 netty_tcnative_linux_aarch64_fedora 库,因为我专门为该特定架构导入了 netty,当我运行
mvn clean package
时,我可以在日志中看到它在 jar 中包含 linux aarch64 库。还有其他方法可以使这项工作有效吗?还是我做错了什么?
错误:
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>
显示 jar 中包含的 netty 库的日志:
[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.
编辑:我想我可能已经在 Raspberry pi 上工作了,但是还有另一个错误要求我切换到 Java 8。我不知道如何切换到 Java 8,因为不知何故该命令不起作用,所以我切换到 Linux x86-64 发行版,但我又遇到了完全相同的错误。我已经导入了库,但它们不会加载。有谁知道如何在 Rpi 上获取 Java 8,或者如何解决这个问题?
不知何故,当我从命令行在 aarch64 Mac 上运行该程序时,它有完全相同的错误,但它仍然有效?我不知道发生了什么事
不是解决方案,但我在 SpringBoot 2.6.6 和 Java 11 下运行的这些版本在 Redhat Linux(x64,不是 ARM)上遇到这个问题。我的软件在我的笔记本电脑上的 Windows 10 下运行良好。我相信这与这些注释有关:
maven 包装在 2.0.49.Final 版本中发生了一些变化。这些更改对于 Maven 用户来说没什么问题,但会给 Gradle 和 Bazel 用户带来一些麻烦。对于 Gradle,解决方案是使用分类器显式声明 tcnative 依赖关系
从这里: https://netty.io/wiki/forked-tomcat-native.html
现在我明白这是指打包而不是运行时,并且 Maven 工作正常(尽管在我的情况下,打包不再简单地在 Gradle 下工作),但即使在我的类路径中使用正确的平台 tcnative jar,我也会得到和你一样的结果。
比较 netty-tcnative-2.0.43.Final-linux-x86_64-fedora.jar(在 2.0.49.Final 重新打包之前)与 netty-tcnative-2.0.51.Final-linux-x86_64-fedora .jar,主要区别在于新的打包仅包含 POM 文件和本机二进制文件,而旧的库包含二进制文件和 java 类目录。有一个java类叫做:
io.netty.internal.tcnative.Library
其中包含使用以下方式将二进制文件加载到内存中的代码:
private static void loadLibrary(String libraryName) {
System.loadLibrary(calculatePackagePrefix().replace('.', '_') + libraryName);
}
现在这个类存在于 netty-tcnative-classes-2.0.43.Final.jar 中,也存在于 netty-tcnative-classes-2.0.51.Final.jar 中,这表明我上面的假设是基于红鲱鱼,但这是我能在这两个库版本之间找到的唯一明显的结构变化。
我希望 io.netty 团队的人能够在我自己编写一个 hacky 静态块来加载库之前为我指明正确的方向。
好吧,事实证明我很蠢,它一直在工作。收到错误后,我只是等了一会儿,它就以某种方式起作用了。我意识到是因为我尝试从我的 Mac 运行我的程序,它比 Raspberry Pi 快得多,并且我意识到它在出现错误后仍然有效,而且只抛出一次错误。因此,如果其他人遇到此错误,请尝试等待,不要中止程序,看看它是否有效。
我的gradle配置
plugins {
id "com.google.gradle:osdetector-gradle-plugin" version "1.7.3"
}
def tcnative_classifier = osdetector.classifier;
// Fedora variants use a different soname for OpenSSL than other linux distributions
// (see http://netty.io/wiki/forked-tomcat-native.html).
if (osdetector.os == "linux" && osdetector.release.isLike("fedora")) {
tcnative_classifier += "-fedora";
}
project.logger.warn("gradle ENV classifier: {}", tcnative_classifier)
ext {
classifier = tcnative_classifier
}
dependencies {
implementation group: 'io.netty', name: 'netty-all', classifier: "$classifier"
implementation group: 'io.netty', name: 'netty-tcnative-boringssl-static', classifier: "$classifier"
}