If I have a java project that consists of several different types of files (pictures, sound, etc) and multiple jar dependencies, what is a good way to package it all into one single jar that can just be double-clicked?
I know jars by themselves are pretty dumb in that they don't look within themselves for files that they depend on (something I only realized after the slightest bit of frustration (understatement)). -- If jar A depends on classes contained inside jar B, putting jar B inside jar A will not work. Jar A must be in the same directory as jar B.
...Now, I know I could just extract all the files from all the other jars and put everything in the same directory. That would sort of work, but I don't want to do it because: 1. It would be messy and 2. it still wouldn't solve the problem of needing to have the sound files in the same directory as the final jar. (For whatever reason, sound files act the exact same way as internal jars)
Basically, I just want to make it so that the files my application depends on aren't obnoxiously visible and ostentatious. So, if there were some solution where I could put everything inside a jar and have it be the only necessary file to run the entire program, that would be optimal. But, I am willing to accept creative/inventive ways to bypass the problem, such as having a batch script in a parent directory execute the jar or something. (I say "or something" because that exact scenario would only work on windows operating systems. ...you know what I mean!)
If you are building an executable jar and have other jars that you need to be available in the classpath, there is a Class-Path: line in the jar's MANIFEST.MF file that lists entries (including jars and directories) to include in the classpath when the main class is run.
I usually use my IDE or ant to build such executable jars and set the Class-Path: header.
By the way, to make your jar executable, set the Main-Class: line in your MANIFEST.MF file.
Here is an example from an executable jar I build:
And here is a corresponding ant target to build this:
If you will use a tool like ant to build your executable jars, it will make the process more easy to repeat, and will also handle strange edge cases for you, like what happens when a header line in MANIFEST.MF gets too long.
If you use Maven, you may a appreciate the onejar-maven-plugin. One major benefit is that all your dependency jars stay in jars, and your code is in its own jar. All of those jars are put in a bigger jar, which is made executable, thus avoiding some potential classpath issues. Read the usage guide and this blog post for more information.
Apache Maven plus shade plugin will do exactly what you need.
Check out the "Shade Plugin where a Main-Class is added to the MANIFEST.MF" section here http://maven.apache.org/plugins/maven-shade-plugin/examples.html
If you use Maven, then I suggest the shade or assembly plugins. If not, then read this: Easiest way to merge a release into one JAR file
If you use the assembly plugin for maven, you can have it download dependencies, build modules and produce an executable jar.
You can extract all the JARs and merge them into one common JAR. There are ANT tasks and Maven plugins readily available for doing just this. Additionally, if you're application is properly written, there is nothing preventing you from putting media files and other resources in the JAR as well. You just need to ensure that these resources are "loaded from the classpath", rather than being loaded from the current working directory.