Create a .jar depending natives / various libs

I’m using javafx, slick2d, kryonet, nifty. I’m quite confused how to build a executionable .jar file tho. It wont work somehow.

I’m using the maven assembly plugin and so far I was able to create a .jar for my server. My server only uses kryonet and javafx, which i have in maven.

Nifty GUI unfortunately i only have locally on my drive, I added a local repository to my pom.xml.

Due to lwjgl natives I chose to use the maven-nativedependencies-plugin, the copy process does work, and the .jar is succesfully created.

I’m not sure where my problem is. To create my server .jar file wasn’t a big deal but i’m hanging on the game client, i think this has it’s origin in slick2d / lwjgl and or nifty gui.

You can find my pom here:
http://pastebin.com/PzG1cSuF

Maven Screenshot if that helps:
http://i.stack.imgur.com/osbnI.jpg (click for better size)

Thanks in Advance, I was googling a lot concerning this, but somehow I can’t get it working.

You need to post a description of the error you have along with a log-output. If you are starting your client, do it from a command line and copy and paste the output to your next forum post.

If you struggle while executing the jar directly, then you need to know, that you can’t simply execute a jar with native dependencies. You need to set a System property pointing to the unpacked natives. There are multiple ways to do it (e.g. from code). The maven-natives-plugin example (https://code.google.com/p/mavennatives/source/browse/#svn%2Ftrunk%2Fmaven-nativedependencies-example) does this by providing a start.bat and start.sh file containing the extra java.library.path parameter to the java call.

It also contains a custom assembly.xml to package the additional files into a zip distribution along with the natives. You are using the standard jar-with-dependencies reference in your assembly plugin configuration, which will not pick up the natives. Better copy and adapt the maven-natives example project to package your game.

There are other solutions involving packaging the natives into your fat-jar and providing code to extract them to a temporary folder and set this as library.path, but it’s a bit more tricky to implement that, so start with a wrapper script.

The optimal solution for the client in the end would be to provide an Installer, that contains a complete (or downstripped) java JRE, all native and other dependencies as well as your game and a small native executable per platform that starts it using the packaged JRE and the needed startup parameters.

Cheers for the quick reply, Ill check this out tomorrow if i got some spare time.

I tested to run the .jar with a shell to get a logoutput with the command java -jar playerClient.jar .
It says it can not locate the main class, eventhough the name of the class is right.

I’ll checkout the maven native plugin ! :slight_smile:

such task i always fix with an embedded ant script (right in the pom).

create directories, unpack zips/jars, move files around, filter, pack/zip, win.

oversimplified, the maven native plugin is just scanning and unpacking binary files. not sure if that will help you if you mix many different libs, which may follow different patterns.

the [icode]maven-dependency-plugin[/icode] is sufficient for unpacking binary file from any artifact to a user defined directory. [icode]maven-antrun-plugin[/icode] is a simple way to filter and move desired files to distribution directory and delete dependency jars containing the unpacked binary files. an artifact which contains other files you want to keep, you can repack it into a new .jar with an exclusion pattern (like jocl requires).

i also dont think that embedding the natives in a final .jar is a good idea. i know libGDX supports it - by unpacking into a temp-directory. why not just gather all natives and put them into a simple folder next to your .jar and use [icode]-Djava.library.path=[some directory][/icode]. not using the temp-directory gives you less garbage left over when your executable fails to cleanup and faster startup times.

for a “distribution” you can just zip the whole thing (with ant).

the only good reason for natives in a jar i can think of is to distribute them as a maven artifact allowing the user to select them by a convenient [icode]classifier[/icode] - like LWJGL does.

o/

Thanks for the reply :slight_smile:
so you suggest I should read about the maven-antrun-plugin, right?
I’ll check this out and hopefully I’ll be able to create an ant script which takes care of this.
I’m really a newb at this, so thanks for the hints!

Stay with the maven-natives-plugin example for now. It does everything you currently need. Regarding your main class not found problem. Make sure your main class is public and really contains a public static void main(String[] args) method…

Yeah I think I’ll do this, the ant script looks way more complex than this.
I’m currently trying to create an assembly.xml file for my needs. :slight_smile:

I got it working so far, i have my natives, libs and resources all in one folder.
If I try to execute my .jar now I’m getting:

Exception in thread “main” java.lang.NoClassDefFoundError: de/lessvoid/nifty/sli
ck2d/NiftyStateBasedGame
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
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)
at build.Start.main(Start.java:11)

This is the library i’ve got locally on my computer.

It’s in my project folder where my src folder etc. is.
In Maven it’s linked via:

  <repository>
     <id>localrepo</id>
     <url>file://${basedir}/nifty-1.4.0-complete</url>
  </repository>

Somehow it’s not working tho, is there a way to check whether maven bound in to local repository correctly?

http://img5.fotos-hochladen.net/uploads/folder1a5co6zt97d.jpg

ya, that’s what i ment.

try the available maven plugins first - if they dont work for you - i mean if they do not support what you would like to do - throw ant on it. sort of last option.

that error is a missing class. inspect the generated manifest file, it must contain the classpath which must contain the class which must exist on the HD pointed to. (not must but should)

my generated MANIFEST is empty somehow ??? :confused:

only contains:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.7.0_17-b02 (Oracle Corporation)

so it does not contain the classpath.

Everything else works fine now with maven and i can even run the .jar, only thing which is missing is my local repository apparently.

Do a mvn clean package to test, if maven finds all dependencies without relying on eclipse background compile. If it does not exit with an error, the repo is not the problem.

The problem here is the classpath to the libraries. For non-native libraries, you have two ways of including them in the client distribution:

  • Either put the jars into some lib folder you distribute along with your application and set the classpath accordingly - this is what the maven-native-plugin example does (pay attention to the maven-jar-plugin configuration in the examples pom).
  • The other way is to include every class of every library you use in your project into your apps jar - this is sometimes called a fat jar and was done by the jar-with-dependencies you used before.

I would go with the example project, because it works, but you can also rebuild the jar-with-dependencies behaviour in your own assembly.xml. See here: http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies (Keep in mind, that you still have to distibute the extra native libraries as separate files, the jar-with-dependencies does not help here…)

I ran the clean package and it says it can not resolve the dependencies.
So the issue probably is my local repository.

I think I failed to install the nifty library properly to my local maven repository.
I thought i could just copy the folder in, but apparently i need to install it with mvn install, right?

yes.

see https://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html and http://maven.apache.org/plugins/maven-install-plugin/usage.html and maybe https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html.

heya, just wanted to say thank and let you guys know that i got it working.
I got a far better understanding how all that works. Cheers!