JNI and java.nio.ByteBuffer

Anders Dahlberg andda715@student.liu.se
Thu Apr 29 16:58:00 GMT 2004


Hello,

I'm new to using gcj so if I've done anything wrong please don't hate me ;)

To the problem:
I'm trying to natively compile lwjgl (light weight java gaming lib, 
www.lwjgl.org) and have come quite close to success (atleast compared to 
my results from a year ago or so).

My problem is probably due to how gcj links jni methods(?).

I'll give a rather long-winded description of the problem now (copied 
from my posts to lwjgl forum at puppygames.net/forums),
all advice you can give are appreciated :)

===
Hello, I've now tried compiling lwjgl with gcj-3.4 (recently released) 
and it's getting very close (I'm on linux btw).

This is what I've done so far (if you spot any errors please let me know):
Installed gcc3.4:

../gcc-3.4.0/configure --prefix=/opt/gcc-3.4.0 --enable-shared 
--enable-languages=java --enable-threads=posix --enable-long-long 
--enable-version-specific-runtime-libs --enable-nls 
--x-includes=/usr/X11R6/include/ --x-libraries=/usr/X11R6/lib/ 
--enable-interpreter --enable-java-awt=gtk --with-x --disable-multilib
Thread model: posix
gcc version 3.4.0


Compiled lwjgl from source (cvs version from a couple of days or so)
* Deleted references to org.w3c (they are implemented in 3.4 - but a 
hassle to link with)
* Deleted SwingAdapter (referenced an unimplemented showMessageDialog 
method)

Compiled lwjgl.jar with gcj into object file (-fjni as default gcj 
native linkage method is cni):
Code:

/opt/.../gcj -c -fjni lwjgl.jar


Linked lwjgl.so to a shared library liblwjgl_native.so:
Code:

/opt/.../gcj -o liblwjgl_native.so -fjni -Wl liblwjgl.so lwjgl.o


* Remember to copy liblwjgl_native.so and liblwjgl.so to /usr/lib and 
soft linking /opt/.../lib/gcjlib.so.5 to /usr/lib too.

So far, all seems to be working.

Here comes the troublesome part:
Tried to compile a test program
Code:

import org.lwjgl.Display;
import org.lwjgl.DisplayMode;
import org.lwjgl.opengl.Window;

public class Test {

     public static void main(String[] args) {
         // Test creation/destruction of window

         try {
             Window.create("LWJGL Game Example");
             Thread.sleep(100);
             System.out.println("Created OpenGL: 1");
             Thread.sleep(1000);

             Window.destroy();
             Thread.sleep(100);
             System.out.println("Window destroy: 1");
         } catch (Exception e) {
             System.err.println("Failed due to " + e);
             System.exit(1);
         }
     }
}

Compiling and linking.
Code:

/opt/.../gcj -c -fjni --classpath=.:lwjgl.jar Test.java
/opt/.../gcj -o test -fjni -Wl liblwjgl_native.so --main=Test Test.o

Running:
Code:

Exception in thread "main" java.lang.NoSuchMethodError: nglCallLists
    at ext_InitializeClass(JNIEnv_, _jclass, _jobject, byte const, void 
()(byte const), int, JavaMethodAndExtFunction) (/usr/lib/liblwjgl.so)
    at extgl_InitializeClass (/usr/lib/liblwjgl.so)
    at extgl_InitOpenGL1_1(JNIEnv_) (/usr/lib/liblwjgl.so)
    at extgl_Initialize (/usr/lib/liblwjgl.so)
    at Java_org_lwjgl_opengl_GLContext_init (/usr/lib/liblwjgl.so)
    at org.lwjgl.opengl.GLContext.init(java.util.Set) 
(/usr/lib/liblwjgl_native.so)
    at org.lwjgl.opengl.GLContext.useContext(java.lang.Object) 
(/usr/lib/liblwjgl_native.so)
    at org.lwjgl.opengl.Window.makeCurrent() (/usr/lib/liblwjgl_native.so)
    at org.lwjgl.opengl.Window.createWindow(int, int, int, int, int) 
(/usr/lib/liblwjgl_native.so)
    at org.lwjgl.opengl.Window.create(java.lang.String, int, int, int, 
int, int) (/usr/lib/liblwjgl_native.so)
    at org.lwjgl.opengl.Window.create(java.lang.String) 
(/usr/lib/liblwjgl_native.so)
    at Test.main(java.lang.String[]) (Unknown Source)


Btw, the same problem when interpreting with gij:
Code:

anders@taif libs $ /opt/gcc-3.4.0/bin/gij -C --classpath=.:lwjgl.jar 
Test.java
anders@taif libs $ /opt/gcc-3.4.0/bin/gij -classpath .:lwjgl.jar Test
Exception in thread "main" java.lang.NoSuchMethodError: nglCallLists
    at ext_InitializeClass(JNIEnv_, _jclass, _jobject, byte const, void 
()(byte const), int, JavaMethodAndExtFunction) (/usr/lib/liblwjgl.so)
    at extgl_InitializeClass (/usr/lib/liblwjgl.so)
    at extgl_InitOpenGL1_1(JNIEnv_) (/usr/lib/liblwjgl.so)
    at extgl_Initialize (/usr/lib/liblwjgl.so)
    at Java_org_lwjgl_opengl_GLContext_init (/usr/lib/liblwjgl.so)
    at _Jv_JNIMethod.call(ffi_cif, void, ffi_raw, void) 
(/opt/gcc-3.4.0/lib/libgcj.so.5.0.0)
    at org.lwjgl.opengl.GLContext.useContext(java.lang.Object) (Unknown 
Source)
    at org.lwjgl.opengl.Window.makeCurrent() (Unknown Source)
    at org.lwjgl.opengl.Window.createWindow(int, int, int, int, int) 
(Unknown Source)
    at org.lwjgl.opengl.Window.create(java.lang.String, int, int, int, 
int, int) (Unknown Source)
    at org.lwjgl.opengl.Window.create(java.lang.String) (Unknown Source)
    at Test.main(java.lang.String[]) (Unknown Source

===
Seems like a bug in gcj to me. If you take a look in extgl_InitOpenGL11 
in ...GL11.cpp you'll see that nglCallLists is the first native method 
with a buffer object in the signature (Ljava/nio/Buffer;), so either the 
signature format is wrong (doesn't seem like it) or else gcj is 
(wrongly) unable to locate the method.

http://java.sun.com/docs/books/tutorial/native1.1/implementing/method.html

gives some pointers as to how method signatures are encoded, maybe you 
should try a

java -s -p GL11

on GL11.class to get the expected signature on nglCallLists.

- elias
===
javap -s -p org.lwjgl.opengl.GL11 | grep -A1 nglCallList
private static native void nglCallLists(int, int, java.nio.Buffer, int);
   Signature: (IILjava/nio/Buffer;I)V
===

also available at:
http://puppygames.net/forums/viewtopic.php?t=549&sid=d03263897e79f50d2eccc55638af0fdc

Thanks in advance
/Anders



More information about the Java mailing list