There's a utility called One-Jar which does what you want, although I'd advise against it. The performance is usually awful.
1 Please elaborate on the awful performance. I use it, and would appreciate the feedback. – Thorbjørn Ravn Andersen Jun 29 '09 at 21:58 I haven't used it for a long time now, but I recall that the classloading performance was very poor, due to the way that the JARs were unpacked.
But like I say, it's been a while. – skaffman Jun 29 '09 at 22:16.
Using the good old Ant: just use zipgroupfileset with the Ant Zip task This will flatten all included jar libraries' content.
I used maven assembly plugin with jar-with-dependencies descriptor.
2 +1. Maven is pretty awesome for taking care of this type of stuff. However I recommend creating a custom assembly rather than using the default jar-with-dependencies since you can get much better results that way. Also, it is worth noting that the latest assembly plugin is somewhat buggy & add multiple copies of your dependencies, so until that is fixed I recommend using the previous version.
– dborba Jun 29 '09 at 19:01.
My feeling is that calling One-Jar's performance awful and poor is unjust. For moderately sized application one can expect startup will take a couple of seconds longer (which does not affect JVM splash screen though). Memory overhead of tens of megabytes is negligible for most environments, except perhaps embedded systems.
Also, One-Jar is capable of automatically extracting some files to the file system, which saves the need to develop an installer in my case. Below is an attempt to quantify the performance impact introduced by One-Jar to my application. It is Swing-based GUI application, consists of 352 classes obfuscated with ProGuard 4.5b2.
One-Jar 0.96 is used to bundle resulting classes with 12MB worth of libraries (ODFDOM, Saxon HE, Xerces, Jaxen, VLDocking, Apache Commons, etc). I have compared performance of the obfuscated jar with the same jar processed by One-Jar. From JVM start to the start of of main() method: 0.5s without One-Jar and 1.7s with One-Jar.
From JVM start to the appearance of application window on the screen: 2.3s without One-Jar and 3.4s with One-Jar. So One-Jar adds 1.1s to startup time. One-Jar will not increase the delay between JVM start and splash image appearing on the screen (if implemented via jar manifest), so the startup time increase is not too annoying for interactive applications.
We are talking about a class loader, so there should be no impact on code execution speed, unless you are extensively using dynamic class loading. Looking at JVM statistics (via jconsole) shows that One-Jar'red version takes more heap memory. For my application the overhead is in the order of tens of MBs.
I saw figures like 16MB vs 40MB, 306MB vs 346MB, 131MB vs 138MB, depending on now much user data the application is handling and now long time ago garbage collector has been executed. The above timing was obtained by taking a timestamp just before starting JVM from Linux shell, in beginning of main() method, and in windowOpened() event handler of my application window. The measurements were taken on a not particularly fast D820 laptop, with dual core 1GHz CPU and 2G or RAM running Ubuntu 8.04.Hope it helps.
If you want to do this there is a tool called Jar Jar Links which will do this for you. Never used it but it is hard to forget the name.
3 minus one million for the pun – skaffman Jun 29 '09 at 19:00.
One-JAR loads all the dependency jars into memory on startup. This may sound horribly inefficient, but nobody has complained to me about it since it was released in 2004. The likely effect of pre-loading is an overall speed up of classloading for the application, since the classloader does not have to repeatedly scan the classpath for resources and classes as the application runs: everything is hashmapped.It's pretty simple to build a lazy loader which would load on-demand: but I'm of the school that says "build-it, measure-it, improve-it if necessary" and so far there has been no need to improve it.
I will keep this in mind for future releases (or if someone else wants to tackle it, that would be great too, since without a very large application to measure against, it's hard to know if changes are improvements).
You can unjar files and repack them using the command line You can use uberjar You can use fatjar.
Fatjar uses one-jar mentioned elsewhere – Thorbjørn Ravn Andersen Jun 29 '09 at 21:59.
Often you can, but sometimes there are unusual legal or technical reasons not to. Legal: For example, we discovered that at the time we wanted to, we could not bundle the JavaMail jar files together into one big package with the rest of our app, but the license agreement said we had to keep them separate. Technical: Another problem might be custom class loaders look for specific resources or classes inside of specific jar files.
This often happens in the context of containers for application servers or ESBs. How: To do it, just unjar everything into one directory, and then rebuild a jar from there. You might have to tweak some settings in the META-INF folder to remove the requests to load the additional jars, and to handle the case where different jars each have a default class to run.
There are some third-party utilities which might help, but unless you know what they are doing, you'd want to be careful.
Eclipse 3.4 and up allows you to do this. Right click your project, select Extract, and navigate to the Runnable Jar option. Select Next.
Choose the appropriate settings and your off and running. Also I seem to recall that this functionality is achieved using the same or similar libraries that FatJar (mentioned above) uses.
This is basically equivalent to Vladimir's answer, because Eclipse creates an Ant zip task to implement this. – finnw Jul 18 '10 at 10:11.
Just for completeness, ProGuard will do this for you, as well as optionally obfuscating and shrinking JARs. The latter function is especially useful for creating final deployment JARs.
Also remember that . Jar files are . Zip files under the covers.
You can use your favorite zip tools to (re)package them. In this case, you would have to deal with the manifest file yourself.
My feeling is that calling One-Jar's performance awful and poor is unjust. For moderately sized application one can expect startup will take a couple of seconds longer (which does not affect JVM splash screen though). Memory overhead of tens of megabytes is negligible for most environments, except perhaps embedded systems.
Also, One-Jar is capable of automatically extracting some files to the file system, which saves the need to develop an installer in my case. Below is an attempt to quantify the performance impact introduced by One-Jar to my application. It is Swing-based GUI application, consists of 352 classes obfuscated with ProGuard 4.5b2.
One-Jar 0.96 is used to bundle resulting classes with 12MB worth of libraries (ODFDOM, Saxon HE, Xerces, Jaxen, VLDocking, Apache Commons, etc). I have compared performance of the obfuscated jar with the same jar processed by One-Jar. From JVM start to the start of of main() method: 0.5s without One-Jar and 1.7s with One-Jar.
From JVM start to the appearance of application window on the screen: 2.3s without One-Jar and 3.4s with One-Jar. So One-Jar adds 1.1s to startup time. One-Jar will not increase the delay between JVM start and splash image appearing on the screen (if implemented via jar manifest), so the startup time increase is not too annoying for interactive applications.
We are talking about a class loader, so there should be no impact on code execution speed, unless you are extensively using dynamic class loading. Looking at JVM statistics (via jconsole) shows that One-Jar'red version takes more heap memory. For my application the overhead is in the order of tens of MBs.
I saw figures like 16MB vs 40MB, 306MB vs 346MB, 131MB vs 138MB, depending on now much user data the application is handling and now long time ago garbage collector has been executed.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.