Creating a JAR with Fat JAR in Eclipse

I'm trying to export my project as a single JAR file using the Fat JAR plugin for Eclipse. However, whenever I run the JAR, I always get a "no lwjgl in java.library.path" error. But I'm definitely sure I've included all the LWJGL files! I even tried including all the jME/lib files, and it still didn't work. Any ideas? I'm also using jME Physics 2… not sure if this makes a difference.

Thanks!

These native library files are loaded (linked at runtime), by the OS. The OS does not look on the classpath, it can only load "real" files by default. One trick is to extract the dll files to the same directory as the jar is launched from before attempting to load them…


u cant compile other jar files into another jar file.



what u need to do is copy all the jar files and native library files in the jme/lib folder into ur game folder where ur compiled game is. then run ur game jar there.

neakor said:

u cant compile other jar files into another jar file.



Yes you can.. :) with Fat Jar:
http://fjep.sourceforge.net/

If you don't believe me, eg look at the demo I have on http://www.tijl.demon.nl/jme/terra/ , it's one jar with others jars in it.. As I explained in the previous post though, doesn't work for native libraries.
llama said:

These native library files are loaded (linked at runtime), by the OS. The OS does not look on the classpath, it can only load "real" files by default. One trick is to extract the dll files to the same directory as the jar is launched from before attempting to load them..



llama is right , I use the FatJar for my project and I just put the lwgl DLLs  in the system32 folder and it works

Do Not put any dll's in there - you will not be able to play other games written with different version of LWJGL

theprism said:

Do Not put any dll's in there - you will not be able to play other games written with different version of LWJGL


Right, plus that would only work on windows, and then only with an admin user.
llama said:


Yes you can.. :) with Fat Jar:
http://fjep.sourceforge.net/

If you don't believe me, eg look at the demo I have on http://www.tijl.demon.nl/jme/terra/ , it's one jar with others jars in it.. As I explained in the previous post though, doesn't work for native libraries.


thats cool~  :D

you could install your own jvm however and put the dll's / libs in the ext directory

Thanks for everyone's help, but I'm still having the same problem. I tried to copy all the files from jME/lib in to the same directory as the JAR (for testing), and I still get the same problem. I can't think why. It gives me a UnsatisfiedLinkError, and then the path where the JAR is, and where liblwjgl.jnilib is. The file is definately in there. Why can't it find it? Thanks!

I'll give you a <hand>  ;), sorry couldn't resist.



when you start your application with the command 'java' you can do smth. like this:



java -cp 'pathsToLibsSeparatedBy:InUnixOr;InWindows' …



Hope I helped.

maybe also adding the current directory to your classpath,  add this ;.;

Okay, I tried that… it still gives me the same error. In any case, should I not need to specify a library path if all the files are in the same directory already? This is what I'm doing right now:



java -cp ./runfiles/lwjgl.jar -Djava.library.path=./runfiles -jar hand.jar



I run that from the desktop. On the desktop is hand.jar, and inside the runfiles directory (also on the desktop), is all the files from jME/lib (including liblwjgl.jnilib, the file it just can't find in there, when it's definitely in there).



Any ideas? I originally wanted to run the whole thing from one JAR… right now I'd be pleased if it ran at all outside of Eclipse…

I'd help more if you give us the actual errror. One thing I can think of is that you changed your default SDK in OSX to Java 6 (which is 64 bit and won't work with the current jME CVS version)

Of course! Sorry. Here you go:



Hand:Desktop hand$ java -cp ./runfiles/lwjgl.jar -Djava.library.path=./runfiles -jar hand.jar
15-Jul-2008 16:08:02 com.jme.app.BaseGame start
INFO: Application started.
15-Jul-2008 16:08:02 com.jme.system.PropertiesIO <init>
INFO: PropertiesIO created
15-Jul-2008 16:08:02 com.jme.system.PropertiesIO load
WARNING: Could not load properties. Creating a new one.
JarClassLoader: Warning: Unable to load native library: java.lang.NullPointerException
15-Jul-2008 16:08:03 class hand.Interface2 start()
SEVERE: Exception in game loop
java.lang.UnsatisfiedLinkError: /Users/hand/Desktop/runfiles/liblwjgl.jnilib:
   at java.lang.ClassLoader$NativeLibrary.load(Native Method)
   at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1822)
   at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1739)
   at java.lang.Runtime.loadLibrary0(Runtime.java:823)
   at java.lang.System.loadLibrary(System.java:1030)
   at org.lwjgl.Sys$1.run(Sys.java:75)
   at java.security.AccessController.doPrivileged(Native Method)
   at org.lwjgl.Sys.doLoadLibrary(Sys.java:68)
   at org.lwjgl.Sys.loadLibrary(Sys.java:84)
   at org.lwjgl.Sys.<clinit>(Sys.java:101)
   at org.lwjgl.opengl.Display.<clinit>(Display.java:111)
   at com.jme.system.lwjgl.LWJGLPropertiesDialog$ModesRetriever.run(LWJGLPropertiesDialog.java:669)
   at com.jme.app.AbstractGame.getAttributes(AbstractGame.java:219)
   at com.jme.app.BaseGame.start(BaseGame.java:62)
   at hand.Interface2.main(Interface2.java:84)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at com.simontuffs.onejar.Boot.run(Boot.java:306)
   at com.simontuffs.onejar.Boot.main(Boot.java:159)
15-Jul-2008 16:08:03 com.jme.app.BaseSimpleGame cleanup
INFO: Cleaning up resources.
15-Jul-2008 16:08:03 com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
15-Jul-2008 16:08:03 com.jme.app.BaseGame start
INFO: Application ending.



EDIT: Ah, I should have checked. The default was set to Java 6. It shows a list, so I thought the way it worked, if a program could use 6, it would try that first, then 5, then 4.2, etc. I guess not. Thanks for your help!

Right, that doesn’t always mean it’s not found, that means it can’t load it…



can you give the output of java -version to confirm you’re not using 1.6 ?





See edit in previous post of hand :slight_smile:

hand said:


EDIT: Ah, I should have checked. The default was set to Java 6. It shows a list, so I thought the way it worked, if a program could use 6, it would try that first, then 5, then 4.2, etc. I guess not. Thanks for your help!


It'd be a bit harsh to expect Java to switch to another JVM on the fly when you want to load a 32-bit library.. :) You can give Java a -d32 argument when starting I think, but not sure that'll fall back from 1.6 to 1.5..