plasma-umass / doppio

Breaks the browser language barrier (includes a plugin-free JVM).
http://plasma-umass.github.io/doppio-demo
MIT License
2.16k stars 175 forks source link

Method flip()Ljava/nio/ByteBuffer; does not exist in class java.nio.ByteBuffer #497

Open emarsden opened 7 years ago

emarsden commented 7 years ago

Attempting to run ABCL triggers this error.

Exception in thread "interpreter" java.lang.NoSuchMethodError: Method flip()Ljav
a/nio/ByteBuffer; does not exist in class java.nio.ByteBuffer.                  
        at org.armedbear.lisp.util.DecodingReader.<init>(DecodingReader.java:87)
        at org.armedbear.lisp.Stream.<init>(Stream.java:165)                    
        at org.armedbear.lisp.Stream.<init>(Stream.java:148)                    
        at org.armedbear.lisp.Stream.<init>(Stream.java:175)                    
        at org.armedbear.lisp.Lisp.<clinit>(Lisp.java:2810) 

ABCL is from https://common-lisp.net/project/armedbear/

jvilk commented 7 years ago

That's an odd error message. [flip() returns a Buffer, not a ByteBuffer](https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip()). Something must be going wrong before ABCL determines the method to invoke!

jvilk commented 7 years ago

ABCL has worked in Doppio before, btw. I remember testing it.

rototor commented 6 years ago

This problem also happens when you build the software with JDK 9 with target JDK 8, because in JDK9 ByteBuffer.flip() returns a ByteBuffer... It used to return a Buffer in JDK8.

And then you try to run this on JDK8 you get exactly this error.

Java-Workaround: Just cast your ByteBuffer to Buffer before calling flip()... i.e. ((Buffer)byteBuffer).flip(). Then you can compile your project with JDK9 and have it running on JDK8.

Note: This is not really related to this project, I only use pure java. But I found this problem report and thought you might be interested in a workaround for this.

jvilk commented 6 years ago

Thanks for the tip; I didn't realized JDK9 had some breaking changes like that! It'd be nice to move to JDK9 someday.

15characterlimi commented 6 years ago

My understanding is that the "correct" way to generate .class files with JDK 9 javac that can be run under JDK 8 java is to not only pass -target 1.8, but to also to set an appropriate bootclasspath, eg. (if $JAVA8_HOME points to an installation of JDK8): --bootclasspath=${JAVA8_HOME}/jre/lib/rt.jar (the --bootclasspath option only exists when targeting versions <= 1.8; version 9 and onwards have --system=... instead to point to a runtime image with system modules).

This way, you will also get an error at compilation time (rather than JDK 8 runtime) if your .java code is trying to use any JDK 9 APIs that don't exist in JDK 8 at all.

If you're not doing this, then javac will warn you: warning: [options] bootstrap class path not set in conjunction with -source 1.8

What javac is trying to tell you with that warning is that the resulting class files might not work under JDK 8's java, because of the above two problems.

15characterlimi commented 6 years ago

Or, more simply, you could use: --release 8 instead of -source 1.8 -target 1.8 --bootclasspath=... See http://openjdk.java.net/jeps/247