[SOLVED]Lwjgl Error: Failed to load the native library: lwjgl

Hello jgo! Today i have been using lwjgl 3, and I have succesfully managed to create a glfw window! The window runs fine with no errors on Eclipse, but when I export it into runnable jar file and try opening it on my Desktop, i get the following error:

Caused by: java.lang.UnsatisfiedLinkError: Failed to load the native library: lwjgl

        at org.lwjgl.LWJGLUtil.loadLibrarySystem(LWJGLUtil.java:329)
        at org.lwjgl.Sys$1.run(Sys.java:36)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.lwjgl.Sys.<clinit>(Sys.java:33)
        at core.Display.<init>(Display.java:36)
        at core.Main.main(Main.java:6)
        ... 5 more

Display.java:

public class Display {
	
	/** The window handle */
	private long wHandle;
	
	// All event callbacks
	GLFWErrorCallback 	  	errorCalls;
	GLFWKeyCallback 	  	keyCalls;
	GLFWCursorPosCallback 	cpCalls;
	GLFWMouseButtonCallback mbCalls;
	
	int width, height;
	String title;
	
	Game game;

	public Display(int width, int height, String title, Game game) {
		this.width = width;
		this.height = height;
		this.title = title;
		this.game = game;
		
		System.out.println("Hello Lwjgl " + Sys.getVersion());
		
		try {
			init();
			loop();
			
			// Dispose of game and resources
			if(game != null)
				game.dispose();
			
			glfwDestroyWindow(wHandle);
			
			// Release all callbacks
			if(keyCalls != null)
				keyCalls.release();
			
			if(cpCalls != null)
				cpCalls.release();
			
			if(mbCalls != null)
				mbCalls.release();
		} finally {
			glfwTerminate();
			errorCalls.release();
		}
	}
	
	private void init() {
		glfwSetErrorCallback(errorCalls = errorCallbackPrint(System.err)); // This will print any lwjgl errors to System.err
		if(glfwInit() != GL_TRUE) {
			throw new IllegalStateException("GLFW cant init!");
		}
		
		// Config window
		glfwDefaultWindowHints();
		glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
		glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
		glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
		glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
		glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
		glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
		
		/** Create window */
		wHandle = glfwCreateWindow(width, height, title, NULL, NULL);
		if(wHandle == NULL) {
			throw new IllegalStateException("Unable to create window, check if have a Opengl version of 3.3 or higher.");
		}
		
		// Set up key callback
		glfwSetKeyCallback(wHandle, keyCalls = new GLFWKeyCallback() {
			@Override
			public void invoke(long window, int key, int scancode, int action, int mods) {
				if(key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
					glfwSetWindowShouldClose(wHandle, GL_TRUE);
			}
		});
		
		// Get video mode of moniter
		ByteBuffer vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
		
		// Center window
		glfwSetWindowPos(wHandle, (GLFWvidmode.width(vidMode) - width) / 2,
	            				  (GLFWvidmode.height(vidMode) - height) / 2);
		
		// Make the Opengl context current in thread
		glfwMakeContextCurrent(wHandle);
		
		// Enable v-sync
		glfwSwapInterval(1);
		
		// Finally ready to show window
		glfwShowWindow(wHandle);
	}
	
	private void loop() {
		// Allow us to use Opengl functions
		GLContext.createFromCurrent();
		
		// Enable blending and alpha transparency for sprites
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glViewport(0, 0, width, height); // Sets viewport
		
		game.start();
		
		// Game Loop
		while(glfwWindowShouldClose(wHandle) == GL_FALSE) {
			glClearColor(0, 0, 0, 1);
			glClear(GL_COLOR_BUFFER_BIT);
			
			game.render();
			game.update();
			
			glfwSwapBuffers(wHandle);
			glfwPollEvents();
		}
	}
}

Main.java:

public class Main {

	public static void main(String[] args) {
		new Display(800, 600, "Lwjgl Test!", new Game());
	}
}

Help!

It can’t find the natives, and you aren’t supposed to export it as a runnable JAR.

Export it as a normal JAR, then use JarSplice to add the natives.

Add the JAR you exported from Eclipse, add all of the Win/Mac/Linux natives, then specify your main class and export as a fat JAR.

  • Jev

When you get that error, then you haven’t set the [icode]org.lwjgl.librarypath[/icode] correctly.
You could copy the native folder to the folder that contains the jar. Then in your main method do this:


if (System.getProperty("org.lwjgl.librarypath") == null) {
    Path path = Paths.get("native");
    String librarypath = path.toAbsolutePath().toString();
    System.setProperty("org.lwjgl.librarypath", librarypath);
}

Does this work for you? :slight_smile:

@SilverTiger Nope I still get same error :frowning:

@kpars Now I get this error:

Exception in thread "main" java.lang.NoClassDefFoundError: core/Display
        at core.Main.main(Main.java:6)
Caused by: java.lang.ClassNotFoundException: core.Display
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more

Looking at the code you posted there doesn’t seem to be any declaration of it being the core package which could be why you are getting that error.

Also one cool thing with LWJGL3 is that you do not need to point to the exact folder containing the system specific natives (in org.lwjgl.librarypath or java.library.path), you can just point to the LWJGL natives folder and it will automatically pick up the relevant natives from the linux, window, mac sub folders. Pretty useful when using the same workspace across different platforms as you do not need to change the native path once set.

@SilverTiger should also reduce your code to

if (System.getProperty("org.lwjgl.librarypath") == null) {
    Path path = Paths.get("native");
    String librarypath = path.toAbsolutePath().toString();
    System.setProperty("org.lwjgl.librarypath", librarypath);
}

Thats the package its in:

[quote]Also one cool thing with LWJGL3 is that you do not need to point to the exact folder containing the system specific natives (in org.lwjgl.librarypath or java.library.path), you can just point to the LWJGL natives folder and it will automatically pick up the relevant natives from the linux, window, mac sub folders. Pretty useful when using the same workspace across different platforms as you do not need to change the native path once set.
[/quote]
I did that and I still get the same error :’(

:o After a long time, I have finally figured out how to export a runnable lwjgl 3.0 jar file(Pretty Amazing):

Steps for anyone with my problem(Eclipse Only):

  1. In eclipse, right click your project and click export

  2. Choose runnable jar file and click “Copy required libraries into a sub-folder next to the generated jar”, and specify the path of your jar

  3. click finish

  4. Download jarsplice and open it

  5. Click the ADD JARS tab, and click Add Jar(s)

6.Then go to the path of your jar and folder, and open up your folder and add all the jars in it, then add the jar that was exported

  1. Then click the ADD NATIVES tab, and click Add Native(s)

  2. Go to the path where you extracted lwjgl and go to the natives folder

  3. Locate the folder of your os and inside locate the folder of acrhitecture(eg. x86 or x64), and add all the dlls in it

  4. Then click the MAIN CLASS tab, and type in your main class(eg. “gzuzboey.game.main”)

  5. Click the CREATE FAT JAR tab and specify the path you where you want your jar to be at

  6. Your Done!

I hope this helps anyone, it sure did help me ;D

You don’t need jarsplice to create a runnable JAR, there are several tools with a better maintenance to do that, you can even use a simple build tool (for example Ant).

But it works…

[quote]there are several tools with a better maintenance to do that, you can even use a simple build tool (for example Ant).
[/quote]
It honestly doesn’t matter, you can get it working either way :stuck_out_tongue:

Some JarSplice bugs have been unfixed for about 4 years:

It matters as if you’re blocked by one of its bugs, you’ll have to do some reverse engineering on it and fix it by yourself which would be probably a lot more time consuming than using a build tool like Ant.

[quote]Some JarSplice bugs have been unfixed for about 4 years:


[/quote]
I didnt even know JarSplice had bugs :point:

[quote]It matters as if you’re blocked by one of its bugs, you’ll have to do some reverse engineering on it and fix it by yourself which would be probably a lot more time consuming than using a build tool like Ant.
[/quote]
While a build tool like Ant might be easier, I was able to use JarSplice without any problems and therefore, I will probably continue to use it :stuck_out_tongue:

Btw, I think Ill have a look at Ant ;D

I’ve used this little function in my games for a while. Make sure it’s the first thing called in your main method. Example:

public static void main(String[] args) {
loadNatives(“path_here”);
// then start your app here
}


        // declare this variable
	private final static String platform = System.getProperty("os.name").toLowerCase();


	/**
	 * Loads the native library from the given path, based on the local machine's operating system.
	 * This MUST BE called before instancing the
	 * @param pathTo The path leading to the /native/ folder (Do not include /native/ in this path!)
	 */
	public static void loadNatives(String pathTo) {
		System.out.println("Machine is running: " + platform);
		if (platform.indexOf("win") >= 0) {
			System.setProperty("org.lwjgl.librarypath", new File(pathTo + "native/windows/").getAbsolutePath());
		} else if (platform.indexOf("mac") >= 0) {
			System.setProperty("org.lwjgl.librarypath", new File(pathTo + "native/macosx/").getAbsolutePath());
		} else if ((platform.indexOf("nix") >= 0 || platform.indexOf("nux") >= 0 || platform.indexOf("aix") > 0)) {
			System.setProperty("org.lwjgl.librarypath", new File(pathTo + "native/linux/").getAbsolutePath());
		} else if (platform.indexOf("sunos") >= 0) {
			System.setProperty("org.lwjgl.librarypath", new File(pathTo + "native/solaris/").getAbsolutePath());
		}
	}

You can also use [icode]LWJGLUtil.getPlatform()[/icode] to get an emum constant for the OS. Also, as of LWJGL 3, you need to specify a folder by 32bit vs 64bit.

[quote=“CopyableCougar4,post:13,topic:52595”]
That was a temporary limitation, you now only have to specify the base folder. The OS and CPU architecture are resolved automatically.

[quote=“Spasi,post:14,topic:52595”]

Which architecture can be resolved automatically? Do you talk only about the “bitness”?

[quote=“gouessej,post:15,topic:52595”]
Whether to use x86 or x64 binaries.

For the architecture, does LWJGL determine the architecture of the system (using native code or some secret Java trickery) or JVM (with System.getProperty("os.arch))? I haven’t tested it, but I’m pretty sure that if it determined the arch. from the JVM, and someone used a x86 JVM on x64 system, it shouldn’t work, because it uses wrong natives on the machine.

[quote=“MrPizzaCake,post:17,topic:52595”]
A x86 JVM on a x64 machine requires x86 binaries.

Oh, okay. As I said, I wasn’t completely sure, I just thought it’d need x64 natives on x64 machines no matter the JVM, due to graphics card and stuff. Anyway, thanks.