I was aware of launch4j, but it only targets Windows (and if you include icons, you have to do that on Windows cause it calls into the win32-API last time i checked). Packr allows you to bundle for any platform from any platform.
It's just insane.
As an alternative suggestion to launch4j -- on end-user desktop installations where one wants native packages -- I think AOT-compilation with tools like RoboVM are ultimately the future:
In fairness, a docker-like chroot jail helps you encapsulate the whole JVM and app server into an immutable unit, which is arguably more manageable than relying on Chef or Puppet or Ansible to keep its configuration stable and versions up to date.
In Java land, you can accomplish that by:
1) Embedding the application server in your own binary; eg, Tomcat and Jetty et al have simple APIs that you can use to run the app server, or
2) Simply packaging them up in a single directory next to each other, or
3) Treating the app server as a deployment fabric (ala Amazon Elastic Beanstalk) and versioning the app server and the wars separately, which has some mighty fine maintenance and deployment advantages.
The only thing you have to do is wire your server into the platform's init scripts, and everything else is self-contained.
Containers are exciting precisely because they don't care about how good or crappy your language interpreter or app server happens to be, whether you run your own data center or use a cloud, etc.
In the Java world, your application dependencies are managed at the (gasp!) application level. You run Maven, Gradle, or whatever... and get a self-contained web archive (i.e. WAR file), with all of the application dependencies bundled. It's just a plain ZIP file, with a standard directory layout.
With a light app server such as Tomcat or Jetty, you literally just drop that file into a particular directory, and it's deployed! You just delete the file (and any contents that the app server unzipped), and it's undeployed!
If it's a console or GUI application rather than a web app, then you just create a JAR file in similar fashion. Maven has its "shade" plugin, and all of the other build systems have similar counterparts... which will bundle up all of the application's dependencies into the JAR file as well. You then ship that monolithic JAR file anywhere, just as you would a ".exe" file. Assuming that you declared a main class when you built the JAR, you can execute it on any system by typing "java -jar file_name.jar"... or by simply double-clicking it in a desktop environment.
Whenever I've dabbled with Python, Ruby, or NodeJS... I've been STUNNED to learn that they follow the ancient Perl convention, of managing application dependencies at the global interpreter level. If I want to write two applications with conflicting sets of dependencies, then I have use a tool such as "virtualenv" (or its Ruby equivalent), to trick my environment into thinking that it's running in a completely different interpreter. NodeJS is somewhat more sane, in that "npm" supports local and global dependencies... but you still have to ensure that you haven't installed a dependency in the wrong place, and that your target machine will have what you need in the correct place.
The current state of distribution and deployment for "dynamic" languages is so insane, that people are actually excited about the idea of shipping an ENTIRE CHROOT JAIL as a deployment unit (i.e. Docker). People are using that in production environments, even though the Docker devs themselves tell you that it's not ready for that yet, because in half-baked form it's still better than the traditional options.
Java has many drawbacks, but distribution and deployment are NOT among them. Most of the people who upvoted this probably just reject Java as old and stuffy, and have not actually done significant work with it. If they had, then there might be at least one comment on this thread pointing out that Packr is a clone of Launch4j (http://launch4j.sourceforge.net)... which has been around for almost a decade now.