Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - How to reduce the size of third-party jars to reduce the size of your application

I am developing a java web application and that includes an applet. That applet is dependent on two jar files:

  • JFreeChart (for plotting graphs at the client side) - 1.7 mb(size of jar file)
  • MySqlJdbcConnector (for storing data, captured at the client side, to a remote database) - .7 mb (size of jar file)

Now, the problem is the size of above two jar files. The total size of my applet jar (myApplet.jar) is 2.5 mb out of which 2.4 mb is because of the above two jar files.

I am not using all the classes in those jar files. Specifically, for jfreechart, I am using a very small number of classes from that library.

==============================Questions======================================

Q1. For creating myApplet.jar file, what I have done is I have unzipped both of the jar files (jfreechart and mySQLJdbcConnector) and then packed the unzipped version of the jar files with the source code of my applet code to create one single jar file (i.e myApplet.jar). Is it the correct way of packing third party jar files with your applet code? Is there any way by which I can optimize this?

Q2. I tried to find the dependencies of the classes of jfreechart library which I am using in my application so as to pack only those dependencies in myApplet.jar. For that purpose, I used DependencyAnalyzer to find the dependencies of all the classes. But later I found it difficult to do so manually because every class (class of jfreechart that I am using in my application) has lot of dependencies and I am using some 15 classes of jfreechart so doing this for every class will be very difficult. So any suggestion on this?

Q3. Is this situation very common that developers encounter or I am missing something because of which I have to do this?

like image 828
Yatendra Avatar asked Apr 07 '11 11:04

Yatendra


People also ask

How can I reduce the size of a jar file?

A jar (and war and ear) are . zip archives that have a specific directory and file structure under them. As they are zipped, the only way to further compress the contents is to remove things from them.

What compression does jar use?

Items stored in JAR files are compressed with the standard ZIP file compression. Compression makes downloading classes over a network much faster. A quick survey of the standard Java distribution shows that a typical class file shrinks by about 40 percent when it is compressed.

How do I run a jar with more memory?

jar will get an initial memory pool of 256 megabytes and a maximum up to 1024 megabytes. In 256m , the m stands for megabytes. You can use g or G to indicate gigabytes. Xmx1g or Xmx1G : Set the maximum memory size to 1 gigabytes.


3 Answers

I'd suggest trying out ProGuard. You can exclude parts of jar files you're not using.

like image 73
darioo Avatar answered Oct 14 '22 17:10

darioo


Yes you can save space by creating a JAR containing only the classes that your applet requires. (I've seen this called an uber-JAR.)

There are various tools for doing this; e.g. ProGuard, Zelix ClassMaster, a Maven plugin whose name I forget and so on.

There are however a couple of issues, at least in the general case:

  • If your code uses dynamic loading (e.g. by calling Class.forName(className)), these tools generally cannot detect the dependency. So to avoid dynamically loaded classes being left out of the final JAR, you need to tell the tool the names of all of all classes that your application might explicitly load that way.

  • You need to take a look at the license of the third party library. IIRC, some licenses require you to include the library in your distributed artifacts in a way that allows people to substitute a different version of the library. One could argue that an uber-JAR makes this hard to do, and therefore could be problematic.

JFreeChart is LGPL, and LGPL is a license that has the requirement above. However MySQL is GPL, which trumps LGPL, and this means that your applet must be GPL'ed ... if you distribute it.


Finally, if you want to minimize the size of your applet JAR, you should NOT include your source code in the JAR. Source code should be in a separate JAR (or ZIP, TAR or whatever) file.

like image 36
Stephen C Avatar answered Oct 14 '22 16:10

Stephen C


A1:

You can create an ant script or use Eclipse or any other IDE to automatically package your applet. But your way is correct, too

A2:

I wouldn't do these things manually. Finding transitive dependencies is very complex. Maybe darioo's answer is a better way to do this.

A3:

This is very common indeed. A couple of hints:

You can always re-build those third party libraries without debug information. That should slightly decrease the size of those libraries.

On the other hand, maybe you shouldn't have a direct connection from your applet to a database. You could create an RMI interface (or something similar) to transfer your SQL and result data to an application server, which actually executes your SQL. This is an important security aspect for your applet, if you don't run this in a safe intranet.

like image 23
Lukas Eder Avatar answered Oct 14 '22 17:10

Lukas Eder