Flink 1.12.0 java.lang.NullPointerException: buffer at org.apache.flink.core.memory.MemorySegment.<init>
Flink 1.12.0 版本,当你使用Temporal Table Join ORC格式的Hive维度表时出现如下异常
java.lang.NullPointerException: buffer
at org.apache.flink.core.memory.MemorySegment.<init>(MemorySegment.java:161) ~[flink-core-1.12.0.jar:1.12.0]
at org.apache.flink.core.memory.HybridMemorySegment.<init>(HybridMemorySegment.java:86) ~[flink-core-1.12.0.jar:1.12.0]
at org.apache.flink.core.memory.MemorySegmentFactory.wrap(MemorySegmentFactory.java:55) ~[flink-core-1.12.0.jar:1.12.0]
at org.apache.flink.table.data.binary.BinaryStringData.fromBytes(BinaryStringData.java:98) ~[flink-table-common-1.12.0.jar:1.12.0]
at org.apache.flink.table.data.StringData.fromBytes(StringData.java:73) ~[classes/:1.12.0]
at org.apache.flink.table.data.ColumnarRowData.getString(ColumnarRowData.java:114) ~[flink-table-runtime-blink_2.11-1.12.0.jar:1.12.0]
at org.apache.flink.table.data.RowData.lambda$createFieldGetter$245ca7d1$1(RowData.java:243) ~[flink-table-common-1.12.0.jar:1.12.0]
at org.apache.flink.table.data.RowData.lambda$createFieldGetter$25774257$1(RowData.java:317) ~[flink-table-common-1.12.0.jar:1.12.0]
at org.apache.flink.table.filesystem.FileSystemLookupFunction.extractLookupKey(FileSystemLookupFunction.java:161) ~[flink-table-runtime-blink_2.11-1.12.0.jar:1.12.0]
at org.apache.flink.table.filesystem.FileSystemLookupFunction.checkCacheReload(FileSystemLookupFunction.java:132) ~[flink-table-runtime-blink_2.11-1.12.0.jar:1.12.0]
at org.apache.flink.table.filesystem.FileSystemLookupFunction.eval(FileSystemLookupFunction.java:103) ~[flink-table-runtime-blink_2.11-1.12.0.jar:1.12.0]
at LookupFunction$8.flatMap(Unknown Source) ~[?:?]
查看堆栈,发现MemorySegment类中的抛出此异常
/**
* Creates a new memory segment that represents the memory of the byte array.
*
* <p>Since the byte array is backed by on-heap memory, this memory segment holds its
* data on heap. The buffer must be at least of size 8 bytes.
*
* @param buffer The byte array whose memory is represented by this memory segment.
*/
MemorySegment(byte[] buffer, Object owner) {
if (buffer == null) {
throw new NullPointerException("buffer");
}
this.heapMemory = buffer;
this.address = BYTE_ARRAY_BASE_OFFSET;
this.size = buffer.length;
this.addressLimit = this.address + this.size;
this.owner = owner;
}
在Flink的Jira里已经有人提了issue,具体可查看https://issues.apache.org/jira/browse/FLINK-20576,但还没有官方回复
我们可以先通过修改源码的方式在上游StringData类中处理掉buffer = null的情况,避免下游抛出异常
修改 org.apache.flink.table.data.StringData
类的 fromBytes(byte[] bytes, int offset, int numBytes)
方法
/**
* Creates an instance of {@link StringData} from the given UTF-8 byte array with offset and number
* of bytes.
*/
BinaryStringData NULL_STRING_DATA = BinaryStringData.fromBytes(new byte[]{});
static StringData fromBytes(byte[] bytes, int offset, int numBytes) {
if (bytes == null) {
System.out.println("bytes is null !!!!!!!!!!!!!!!!!!!!!!!!!");
return NULL_STRING_DATA;
}
return BinaryStringData.fromBytes(bytes, offset, numBytes);
}
注意要放在 org.apache.flink.table.data
目录下,在自己的IDE里建一个相同路径的目录,这时在IDE里执行程序已经不会抛出该异常了
在服务器端执行我们还需要替换 lib/flink-table_2.11-1.12.0.jar
包中的该class,记得替换前把该jar包备份一份
在服务器上创建 org.apache.flink.table.data
目录,将编译好的StringData.class上传到该目录下: org/apache/flink/table/data/StringData.class
执行如下命令 jar -uvf flink-table_2.11-1.12.0.jar org/
就可以把修改后的StringData.class覆盖原jar中的文件了,之后在服务器上执行flink job也避免该异常出现了