Distribution using maven/launch4j with natives (Slick2D/lwjgl)

First, I’m not really sure where I should be posting this so I just chose General discussions. If this is the wrong place for it, please move it.

I’m trying to perfect my distribution process. I’ve spent tons of hours working on getting everything just how I want it and I think I’m close to my final goal.
My final goal is to be able to only require a single exe to run my games. However, I’m not sure this will be possible but that’s why I’ve come here.

Currently, I’m using maven in conjunction with the launch4j, shade, and assembly plugin. Currently it works like this: shade plugin builds the executable jar with all dependencies inside it, launch4j plugin takes that executable jar and wraps it in to an exe, then the assembly plugin places the exe and my natives folder in to a single zip folder. I’m fairly happy with this design currently but I’d really like it more if I only had to distribute a single exe and didn’t have to worry about users moving the exe and not the natives folder (though I don’t think most would do that, but I’d like to take the possibility away entirely).

I’m wondering if it’s possible to use launch4j to somehow include the natives folder in such a way that the jar has access to them, but the folder is still inside the exe. This would get around the fact that you cannot load native libraries from within a jar.

Another method I have considered is storing the natives folder in the jar and then when the jar is ran, have it extract the natives to folder to some place like ~/.myapp/natives. This feels like a hacky workaround to me though but if it’s a common practice, I’d be open to suggestions on ways to make this method be more robust (should I only do it once? everytime its ran? etc).

If you are interested in seeing how I have my current distribution process setup, you can look at my pom file here: http://pastebin.com/fQtCWdwG and the dist.xml the assembly plugin uses here: http://pastebin.com/kh10MrFE.

You can use kappa’s JarSplice tool which combines all dependencies and natives in 1 fat jar. It does this by extracting the natives to a temporary folder.

You can then use this to wrap it in an EXE with Launch4j.

I don’t think I can use that automatically with maven. I’ll try to to dig deeper with it and see if it can be done though.

One-Jar supports a “binlib/” folder in the root of the jar that contains your natives, and the packer has ant, maven, and sbt support. One-jar’s approach however is nested jars and a custom classloader, which may or may not play nicely with launch4j.

Related: I’m a big fan of JarSplice, but not such a huge fan of its front-end GUI – the file chooser seems bugged on my Mac, it doesn’t remember my last used directory (i.e. through Preferences) (scratch that; this was added recently), there is no way to automate the process, error messages may not show without running through command line, etc. Is the source available somewhere? It would be great if somebody ‘ported’ it somehow to something like Maven or ANT, to allow integration with building and distribution (assuming such a thing is possible).

Hi

I use getdown as an installer and wrap that up in an exe, that means the user gets 1 exe to download, this then goes off and downloads and installs everything else. It’s still not a slick as a native installer, but I had even more issues with those I tried.

Endolf

If by automation you mean you want to pass arguments to an executable and have it spit out a JAR, then I can whip up one if you give me a day or two.

This is the approach I’m currently using, but I agree with you that it doesn’t feel like a robust solution. I only extract the natives if they are not already present. However, be sure to put the version number in the filenames to prevent everything from breaking when a new version of the native library is released.

I’ll see what I can accomplish with one-jar and maven. If that doesn’t work out well then I’ll probably work on a system like this. Mr Gol, would you mind sharing some code examples? Do you have a project that uses this on github or something like that? It would be much appreciated.

After messing around with the one-jar maven plugin it seems like it won’t do what I need. I can’t seem to stop my java library jar files from being added (that was its original purpose). It also appears as though it’s not being actively maintained/updated anymore either which may cause problems in the future. Looks like it’s time to work on extracting the natives from the jar in the most robust way possible so I can just copy/paste that code in to new projects and have it just work.

Would you still like me to make that tool for you?

Thank you for the offer but probably not. I can get it working with the tools mentioned. I’m just trying to get something working with maven (one-jar maven plugin was close but had some flaws).

I decided to just go for the extract the dlls from the jar solution. So right now I’m trying to make a method that will copy all the files in a folder in a jar to ~/.appname/natives to be loaded from the program.
To clarify:
This is what the contents of my jar looks like: http://i.imgur.com/rdDiV.png
I’m trying to copy all of the dll/so/jnilib files in the natives folder to a folder in the user’s home directory. I can get this working if I specify each file but for some reason I can’t get it to just loop through every file in the natives folder.

Any help with this task would be appreciated, but don’t feel like you have to.

Use Jarfile and enumerate through all the entries, extracting only the ones that end with .DLL for Windows, .SO for Linux, or .JNILIB and .DYLIB for Mac OS X

How do I use JarFile on itself?


new File(AnyClassInsideJar.class.getProtectionDomain().getCodeSource().getLocation().toURI());

:slight_smile:

Sweet, I have it working. It’s only limitation now is you can’t run the jar if the path to it contains nonASCII characters like §☼ƒ. I tried to decode the path with URLDecoder.decode but it doesn’t save it from utf characters. Oh well, I can live with that limitation.

Why doesn’t it work on non ASCII characters?

And anyway, I still took the liberty of writing my own FatJar, which is very similar to the JarSplice tool, except that it is only command-line based. AKA: automatable :slight_smile:

Here is the Jar. The usage can be seen by simply running it without any arguments.

Here is the source of FatJar.java. This is what creates the Fat Jar.
Here is the source of FatJarLauncher.java. This is what runs your Fat Jar.

It works on Windows for all I know. Could others test it on other platforms? Also, is there anything I missed or want me to add?