![](/img/trans.png)
[英]Kafka with Zookeeper 3.5.7 Crash NoSuchMethodError: java.nio.ByteBuffer.flip()
[英]Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer
我有一个方法如下,它已经正常运行了很长时间:
private String loadFromFile(){
RandomAccessFile inFile = null;
FileChannel inChannel = null;
StringBuilder sb = new StringBuilder();
try {
inFile = new RandomAccessFile(this.latestImageFile, "r");
inChannel = inFile.getChannel();
ByteBuffer bb = ByteBuffer.allocate(2046);
while( inChannel.read(bb) != -1){
bb.flip();
while(bb.hasRemaining()){
char c = (char) bb.get(); // read character at current position and set the pointer to current position + 1
sb.append(c);
}
bb.clear();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inChannel != null) try {inChannel.close(); } catch (IOException e){}
if (inFile != null ) try { inFile.close(); } catch (IOException e) {}
}
return sb.toString();
}
但是,今天我在服务器上编译并运行程序后,启动程序时记录了以下异常。 它显示未找到 flip() 方法:
Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
at com.rt.stream.s.exch.OBWorker.loadFromFile(OBWorker.java:271)
at com.rt.stream.s.exch.OBWorker.initAndLoadOBs(OBWorker.java:184)
at com.rt.stream.s.exch.OBWorker.<init>(OBWorker.java:145)
at com.rt.stream.s.exch.OBWorkerMgr.initFromProperties(OBWorkerMgr.java:217)
at com.rt.stream.s.exch.OBWorkerMgr.init(OBWorkerMgr.java:132)
at com.rt.stream.s.exch.OBWorkerMgr.main(OBWorkerMgr.java:511)
请问有人对此有任何想法吗?
程序运行环境规范是这样的:
服务器:
发展:
IDE:版本:2019-09 R (4.13.0)
JDK:jdk-11.0.1
maven:apache-maven-3.3.3(应用以下配置)
<source>1.8</source>
<target>1.8</target>
在搜索了一段时间并通过在 8 和 11 之间切换已安装的 JDK 进行验证后,我发现 ByteBuffer class 中的几个方法(例如,翻转(),清除() )有一些更改(new overridden methods)
。
在Java 8中,在调用ByteBuffer class的flip()
方法时,由于没有实现该方法,所以实际上是从扩展的class中调用方法,Buffer; 返回Buffer
object 如下:
在缓冲区class 中:
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
However, in Java 11, ByteBuffer class has implemented its own flip() method, and the returning object is changed from Buffer to ByteBuffer (This change should be started from Java 9):
在字节缓冲区class中:
ByteBuffer flip() {
super.flip();
return this;
}
然而,默认情况下,javac 针对最新版本的平台 API 进行编译。 因此,编译后的程序可能会意外使用仅在当前平台版本中可用的 API。 无论传递给 -source 和 -target 选项的值如何,此类程序都无法在旧版本的平台上运行。 这是一个长期的可用性痛点,因为用户希望通过使用这些选项,他们将获得可以在 -target 指定的平台版本上运行的 class 文件。
该声明可以参考这里: http://openjdk.java.net/jeps/247
因此,为了解决此类问题,有两种方法:
通过使用新引入的命令行选项,可以在编译期间处理:
ie javac --release N <source files> which is equals to: for N < 9: -source N -target N -bootclasspath <documented-APIs-from-N>, for N >= 9: -source N -target N --system <documented-APIs-from-N>.
或者我们可以在代码中处理它,作为预防方法,在调用相应方法之前将 ByteByffer 显式转换为 Buffer:
((缓冲区) bb).flip();
为了强制它调用扩展类的方法(以防编译过程没有考虑新的命令行选项):
private String loadFromFile(){ RandomAccessFile inFile = null; FileChannel inChannel = null; StringBuilder sb = new StringBuilder(); try { inFile = new RandomAccessFile(this.latestImageFile, "r"); inChannel = inFile.getChannel(); ByteBuffer bb = ByteBuffer.allocate(2046); while( inChannel.read(bb).= -1){ ((Buffer)bb);flip(). // explicitly casting while(bb.hasRemaining()){ char c = (char) bb;get(). sb;append(c). } ((Buffer) bb);clear(). // explicitly casting } } catch (IOException e) { e;printStackTrace(). } finally { if (inChannel;= null) try {inChannel.close(); } catch (IOException e){} if (inFile.= null ) try { inFile;close(); } catch (IOException e) {} } return sb.toString(); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.