线程&"main&"中的异常java.lang.NoSuchMethodError:java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer [英] Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer

查看:2017
本文介绍了线程&"main&"中的异常java.lang.NoSuchMethodError:java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种下面的方法已经运行了很长时间了:

I have a method as of below which has been running properly for a long time:

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()方法:

However, today after I have compiled and run the program on a server, below exception was logged when starting the program. It shows a flip() method is not found:

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)

有人对此有任何想法吗?

程序运行环境规范如下:

Anybody has any idea on it please?

The program running environment specification is like this:

服务器:

  1. openjdk版本"1.8.0_242"

发展:

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

  1. IDE: Version: 2019-09 R (4.13.0)

JDK:jdk-11.0.1

JDK: jdk-11.0.1

maven:apache-maven-3.3.3(应用以下配置)

maven: apache-maven-3.3.3 (with below configuration applied)

   <source>1.8</source>   
   <target>1.8</target>

推荐答案

搜索了一段时间并通过在8和11之间切换已安装的JDK进行了验证之后,我发现有一些更改(新的覆盖方法)应用于ByteBuffer类中的几种方法(例如 flip(),clear()).

After searching for a while and verified through switching the installed JDK between 8 and 11, I have found that there are some changes (new overridden methods) applied to several methods (e.g. flip(), clear() ) in ByteBuffer class.

在Java 8中,在调用ByteBuffer类的 flip()方法时,由于该方法没有实现,因此它实际上是从扩展类Buffer中调用该方法的;这将返回 Buffer 对象,如下所示:

In Java 8, while calling flip() method of ByteBuffer class, since it has no implementation for this method, so it is actually calling the method from extended class, Buffer; which is returning Buffer object as below:

Buffer 类中:

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

但是,在Java 11中,ByteBuffer类实现了自己的flip()方法,并且返回的对象从Buffer更改为ByteBuffer(此更改应从Java 9开始):

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):

ByteBuffer 类中:

ByteBuffer flip() {
    super.flip();
    return this;
}


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


Since I'm using JDK 11 (higher JDK version) to compile the program for running on Java 8, the mentioned exception would occasionally encountered accordingly to javadoc:

但是,默认情况下,javac会针对最新版本的Java进行编译平台API.因此,编译后的程序可能会意外使用仅在平台的当前版本中可用的API.这样的程序不能在平台的旧版本上运行,无论传递给-source和-target选项的值.这是一个长期可用性的痛点,因为用户期望通过使用这些选项,他们将获得可以在平台上运行的类文件-target指定的版本.

By default, however, javac compiles against the most-recent version of the platform APIs. The compiled program can therefore accidentally use APIs only available in the current version of the platform. Such programs cannot run on older versions of the platform, regardless of the values passed to the -source and -target options. This is a long-term usability pain point, since users expect that by using these options they'll get class files that can run on the the platform version specified by -target.

可以在此处引用该语句: http://openjdk.java.net/jeps/247

The statement could be referenced here: http://openjdk.java.net/jeps/247

因此,要解决此类问题,有两种解决方法:

So, for resolving this kind of problems, the are 2 ways to do so:

通过使用新引入的命令行选项,可以在编译期间进行处理:

One can handle in the duration of compilation, by making use of a newly introduced command-line option:

i.e.
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>.  


方法2

或者我们可以在代码中作为预防措施来处理它,方法是在调用相应的方法之前将ByteByffer显式转换为Buffer:


Approach 2

Or we can handle it in codes, as precaution methods, by explicitly casting the ByteByffer as Buffer before calling corresponding methods:

(((缓冲区)bb).flip();

((Buffer) bb).flip();

为了强制它调用扩展类的方法(以防编译过程未考虑新的命令行选项):

which in order to force it calling extended class's method (in case the compilation process hasn't taken the new command-line options into consideration):

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();
}

这篇关于线程&amp;"main&amp;"中的异常java.lang.NoSuchMethodError:java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆