I can't compile a simple NeHe Lesson

Hi:

I’ve used JOGL before on windows. I’ve been programming in something else for a while now and I have passed to a x64 Kubuntu. So I download NetBeans and JOGL from the package manager and then I try to compile Lesson02 from NeHe. Making a couple of changes since the functions I needed to implemente used AutoDrawables and not the Drawables than the lesson had. Anyway the code looks like this:


import java.awt.*;
import java.awt.event.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.GLCanvas;

public class lesson02 {
 static class Renderer
    implements GLEventListener,
               KeyListener
  {
    /** Called by the drawable to initiate OpenGL rendering by the client.
     * After all GLEventListeners have been notified of a display event, the 
     * drawable will swap its buffers if necessary.
     * @param gLDrawable The GLDrawable object.
     */    
    public void display(GLAutoDrawable gLADrawable)
    {        
      final GL gl = gLADrawable.getGL();
      gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
      gl.glLoadIdentity();
      gl.glTranslatef(-1.5f, 0.0f, -6.0f);
      gl.glBegin(GL.GL_TRIANGLES);		// Drawing Using Triangles
        gl.glVertex3f( 0.0f, 1.0f, 0.0f);	// Top
        gl.glVertex3f(-1.0f,-1.0f, 0.0f);	// Bottom Left
        gl.glVertex3f( 1.0f,-1.0f, 0.0f);	// Bottom Right
      gl.glEnd();				// Finished Drawing The Triangle
      gl.glTranslatef(3.0f, 0.0f, 0.0f);
      gl.glBegin(GL.GL_QUADS);           	// Draw A Quad
        gl.glVertex3f(-1.0f, 1.0f, 0.0f);	// Top Left
        gl.glVertex3f( 1.0f, 1.0f, 0.0f);	// Top Right
        gl.glVertex3f( 1.0f,-1.0f, 0.0f);	// Bottom Right
        gl.glVertex3f(-1.0f,-1.0f, 0.0f);	// Bottom Left
      gl.glEnd();				// Done Drawing The Quad
      gl.glFlush();
    }
    
    
	 /** Called when the display mode has been changed.  <B>!! CURRENTLY UNIMPLEMENTED IN JOGL !!</B>
    * @param gLDrawable The GLDrawable object.
    * @param modeChanged Indicates if the video mode has changed.
    * @param deviceChanged Indicates if the video device has changed.
    */
    public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged)
    {
    }
    
	 /** Called by the drawable immediately after the OpenGL context is 
    * initialized for the first time. Can be used to perform one-time OpenGL 
    * initialization such as setup of lights and display lists.
    * @param gLDrawable The GLDrawable object.
    */
   public void init(GLAutoDrawable gLDrawable)
    {
      final GL gl = gLDrawable.getGL();
      gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
      gl.glShadeModel(GL.GL_FLAT);
      gLDrawable.addKeyListener(this);
    }
    
  
	 /** Called by the drawable during the first repaint after the component has 
    * been resized. The client can update the viewport and view volume of the 
    * window appropriately, for example by a call to 
    * GL.glViewport(int, int, int, int); note that for convenience the component
    * has already called GL.glViewport(int, int, int, int)(x, y, width, height)
    * when this method is called, so the client may not have to do anything in
    * this method.
    * @param gLDrawable The GLDrawable object.
    * @param x The X Coordinate of the viewport rectangle.
    * @param y The Y coordinate of the viewport rectanble.
    * @param width The new width of the window.
    * @param height The new height of the window.
    */
    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height)
    {
      final GL gl = gLDrawable.getGL();
      final GLU glu = new GLU();
      if (height <= 0) // avoid a divide by zero error!
        height = 1;
      final float h = (float)width / (float)height;
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL.GL_PROJECTION);
      gl.glLoadIdentity();
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glLoadIdentity();
    }

    /** Invoked when a key has been pressed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key pressed event.
     * @param e The KeyEvent.
     */
    public void keyPressed(KeyEvent e)
    {
      if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
        System.exit(0);
    }
    
    /** Invoked when a key has been released.
     * See the class description for {@link KeyEvent} for a definition of
     * a key released event.
     * @param e The KeyEvent.
     */
    public void keyReleased(KeyEvent e) {}
    
    /** Invoked when a key has been typed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key typed event.
     * @param e The KeyEvent.
     */
    public void keyTyped(KeyEvent e) {}
  }

  /** Program's main entry point
   * @param args command line arguments.
   */
  public static void main(String[] args)
  {
    Frame frame = new Frame("Lesson 2: Your First Polygon");
    GLCanvas canvas = new GLCanvas(new GLCapabilities());    
    canvas.addGLEventListener(new Renderer());
    frame.add(canvas);
    frame.setSize(640, 480);
    frame.addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent e)
      {
        System.exit(0);
      }
    });
    frame.show();
    canvas.requestFocus();
  }
}

I have created new libraries (by using the tools -> libraries option to create the library JOGL and I included the path for jogl.jar, jogl-1.1.1.jar, and gluegen-rt-1.1.1,jar ) and added them to the project. However when I compile I get this error:


Exception in thread "main" java.lang.UnsatisfiedLinkError: no gluegen-rt in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1698)
        at java.lang.Runtime.loadLibrary0(Runtime.java:840)
        at java.lang.System.loadLibrary(System.java:1047)
        at com.sun.gluegen.runtime.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:102)
        at com.sun.gluegen.runtime.NativeLibLoader.access$000(NativeLibLoader.java:51)
        at com.sun.gluegen.runtime.NativeLibLoader$1.run(NativeLibLoader.java:70)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.gluegen.runtime.NativeLibLoader.loadGlueGenRT(NativeLibLoader.java:68)
        at com.sun.gluegen.runtime.NativeLibrary.ensureNativeLibLoaded(NativeLibrary.java:399)
        at com.sun.gluegen.runtime.NativeLibrary.open(NativeLibrary.java:163)
        at com.sun.gluegen.runtime.NativeLibrary.open(NativeLibrary.java:129)
        at com.sun.opengl.impl.x11.DRIHack.begin(DRIHack.java:109)
        at com.sun.opengl.impl.x11.X11GLDrawableFactory.<clinit>(X11GLDrawableFactory.java:99)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:186)
        at javax.media.opengl.GLDrawableFactory.getFactory(GLDrawableFactory.java:111)
        at javax.media.opengl.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:520)
        at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:131)
        at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:90)
        at lesson02.main(lesson02.java:127)
Java Result: 1
BUILD SUCCESSFUL (total time: 6 seconds)

Can any one tell what I’ve done wrong or how I can fix this problem?

Thank you very much for any help.

You need to specify the location of the natives in the “VM options” field of the run category of your project properties like


-Djava.library.path=/path/to/jogl-natives:/path/to/gluegen-natives

You only need to specify the directory, where tho .so files are in, not the lib files directly.

Or you download the Netbeans OpenGL Pack and create a new project based on the provided templates. You have to remove the jogl and gluegen related entries you created in netbeans library manager before, though.

So I deleted my “created” libraries and I did the Netbeans OpenGL pack thing. then I tried to execute the rotating gears example. I got an identical error message but for jogl this time. I noticed how the gluegen-rt was configured (int tools->libraries option) added jogl.jar path to the JOGL library and I it worked.

So then I went back to my example and I tried to compiled it and I get the exact same errror as before. I appreciate your help. But could anyone help me understand what is going on?

Thanks a lot in advance.

I already did. You are missing the java.library.path VM option. The OpenGL pack takes care of this, as long as you use the provided templates (it does some more to enable webstart and make multiple distributions for all supported platforms). So if you don’t want to copy your code into a new project created using a JOGL template, just follow the advice in the first paragraph of my last answer.

In lamens term’s you have to tell each Java project you have to use the external JOGL and GluGen Libraries, otherwise how else is JVM supposed to know where the commands your using are coming from. I remember the first time I used JOGL I struggled with this sincerely.

edit: Just follow cylabs advice. It wasn’t by fluke that it worked for you once…

Ok I need my allready compiled projects to work again. So I tried following your advice. And I right-clicked on project properties and added this line


Djava.library.path=/usr/lib/jni-natives:/usr/lib/jni-natives 

to the VM Options field in the Run category of the project properties.

This folder (/usr/lib/jni) contains libjogl.so and libgluegen-rt.so. I’m assuming these are the libraries you were referring to.

However now I get this error


Exception in thread "main" java.lang.NoClassDefFoundError: Djava/library/path=/usr/lib/jni-natives:/usr/lib/jni-natives
Caused by: java.lang.ClassNotFoundException: Djava.library.path=.usr.lib.jni-natives:.usr.lib.jni-natives
        at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
Could not find the main class: Djava.library.path=/usr/lib/jni-natives:/usr/lib/jni-natives. Program will exit.
Java Result: 1

Did I do something wrong?

-Djava.library.path=(…), the - is important.

My line now reads


-Djava.library.path=/usr/lib/jni-natives:/usr/lib/jni-natives

And I now get the original error:


init:
deps-jar:
compile:
run:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no gluegen-rt in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1698)
        at java.lang.Runtime.loadLibrary0(Runtime.java:840)
        at java.lang.System.loadLibrary(System.java:1047)
        at com.sun.gluegen.runtime.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:102)
        at com.sun.gluegen.runtime.NativeLibLoader.access$000(NativeLibLoader.java:51)
        at com.sun.gluegen.runtime.NativeLibLoader$1.run(NativeLibLoader.java:70)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.gluegen.runtime.NativeLibLoader.loadGlueGenRT(NativeLibLoader.java:68)
        at com.sun.gluegen.runtime.NativeLibrary.ensureNativeLibLoaded(NativeLibrary.java:399)
        at com.sun.gluegen.runtime.NativeLibrary.open(NativeLibrary.java:163)
        at com.sun.gluegen.runtime.NativeLibrary.open(NativeLibrary.java:129)
        at com.sun.opengl.impl.x11.DRIHack.begin(DRIHack.java:109)
        at com.sun.opengl.impl.x11.X11GLDrawableFactory.<clinit>(X11GLDrawableFactory.java:99)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:186)
        at javax.media.opengl.GLDrawableFactory.getFactory(GLDrawableFactory.java:111)
        at javax.media.opengl.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:520)
        at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:131)
        at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:90)
        at lesson02.main(lesson02.java:126)
Java Result: 1

You only have to set a location once per unique directory, but this is not the error here. Are you sure, the gluegen-rt.so is in “/usr/lib/jni-natives”? If so, are you sure, you have the right natives-version (x64)?

Try the natives shipped with the Netbeans OpenGL-Pack:


-Djava.library.path=/home/<username>/.netbeans/6.5/gluegen-runtime/gluegen-rt.jar-natives-linux-amd64:/home/<username>/.netbeans/6.5/jogl-runtime/jogl.jar-natives-linux-amd64

You have to replace with the linux-user you are using. And take a look, if the files are really located there :wink:

  1. No the file is not jni-natives is just jni. I added the -natives because that was the example I was given. I’ve must of misunderstood.

  2. the file names are: libjogl.so and libgluegen-rt.so NOT jogl.so and gluegen-rt.so

I’ll try your suggestions.

In that example I was trying to say where “jogl-natives” was meant as a term for the native library files. When talking about “native” libraries in contrast to “jar” libraries, we talk about (C-)code compiled to a specific platform. The “java.library.path” is a java system variable that tells the java VM where to look for those native libraries when they are needed by java code.

This is the same concept like the PATH environment variable allows the shell to find executable binaries or the LD_LIBRARY_PATH environment variable telling your *nix OS where to search for it’s dynamic link libraries. In fact you could also add the location of the jogl/gluegen natives to the latter and java would also find them.

You are right. I use windows, so I guessed the names.

Thank you so very much. I changed the line to: ;D


-Djava.library.path=/usr/lib/jni

And it worked like a charm.

However one question remains. How do I execute the program outside of the Netbeans Environment? I have to write the above line each time I execute the program?
Thanks

Yep. Usually you package your application and all your dependencies into a zip for distribution and when you extraxt this, you should have something like


start-linux-amd64.sh
start-windows-i586.bat
start-otherPlatform1...
start-otherPlatformN...
lib/
   jogl.jar
   gluegen.jar
   otherDependency1.jar
   otherDependencyN.jar
   linux-amd64/
      libgluegen-rt.so
      libjogl.so
      libOtherNative1.so
      libOtherNativeN.so
   windows-windows-i586/
      gluegen-rt.dll
      jogl.dll
   otherPlatform1/
      ...
   otherPlatformN/
      ...

In every start script you would write the commands necessary to start your app under this specific platform including the “-Djava.library.path=lib/” argument to the java command.

Another option is to use Java Webstart. If you base your project on one of our templates, you can enable webstart in the projects properties.