概述

因为公司业务需求,需要将一部分原本已经用C/C++写好的程序封装到flink内部使用。

操作系统

CentOS 7

使用的技术和工具

flink 1.17.1

JDK 19.0.2

JNA 5.12.1

maven 3.9.4

技术实现

利用JNA将C/C++的程序封装到JAR包里面,然后结合flink依赖,打包运行即可。

注意:

JNA可以加载JAR包内部的so库

Q&A

Q: 1.Exception in thread “main” java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.net.DatagramSocket java.net.DatagramSocket.delegate accessible: module java.base does not “opens java.net” to unnamed module @26f67b76

2.Exception in thread “main” java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not “opens java.lang” to unnamed module @1a810908

3.Exception in thread “main” java.lang.reflect.InaccessibleObjectException: Unable to make field private final sun.nio.ch.DatagramChannelImpl sun.nio.ch.DatagramSocketAdaptor.dc accessible: module java.base does not “opens sun.nio.ch” to unnamed module @26f67b76

A: 执行的时候加上以下选项 –add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.math=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED

Q: java.lang.Exception: Could not create actor system A: 百度发现是打包的flink依赖包版本不对(运行是1.17.1,JAR包用的是1.13.1)

Q: Exception in thread “main” org.apache.flink.api.common.InvalidProgramException: java.io.FileDescriptor@3a82f6ef is not serializable. The object probably contains or references non serializable fields

A: DatagramSocket对象内部存在不支持序列化的字段,所以不能定义为SourceFunction派生类的属性。 因为flink分布式的特性,所以JAR包内的类都需要支持序列化。 为了避免该问题,将DatagramSocket挪到run函数内部初始化即可

Q: JNA加载动态库(以下称为主库)的时候,不会加载主库所依赖的其他动态库

A: 这种情况解决方法有以下几种 1. 导出LD_LIBRARY_PATH 2. 将主库所依赖的动态库编译成.a,一起打包到主库 3. 将依赖库所在的路径添加到能被搜索到的路径,具体请查看“参考链接”

Q: java.lang.UnsatisfiedLinkError:Unable toload library ‘NSIPLite’: Can’t obtain InputStream for linux-aarch64/libNSIPLite.so A: flink在加载动态库的时候,根据平台架构区分需要加载的动态库路径,在resources/下面创建对应的平台架构目录(linux-aarch64/linux-x86_64/liunx-x86之类的),将对应的动态库放置到对应的平台架构目录,重新打包即可

参考链接

在JDK17尝鲜Flink1.17 flink1.12.2之后的版本和scala的兼容性问题 Linux下5种动态库运行时搜索路径的方法

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。