繁体   English   中英

线程“主”中的异常 java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer

[英]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)

请问有人对此有任何想法吗?

程序运行环境规范是这样的:

服务器:

  1. openjdk 版本“1.8.0_242”

发展:

  1. IDE:版本:2019-09 R (4.13.0)

  2. JDK:jdk-11.0.1

  3. 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;
}

由于我使用 JDK 11(更高的 JDK 版本)编译程序以在 Java 8 上运行,因此偶尔会遇到 javadoc 所提到的异常:

然而,默认情况下,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM