This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I am trying to create an executable jar out of a Java project which uses the jExcel API (jxl.jar). The project has been created using Eclipse 3.1 M7. I used the "Export as Jar file" tool in Eclipse to create the said jar file. But, when i try to run the jar, it says: "Fatal exception occured. Program will exit." It is not able to find the "BiffException" class, says the exception trace.
What could be the reason? The program runs perfectly fine from within Eclipse.
In fact, i am facing this problem only when i refer any external jars in my project. If the project just uses the standard Java api, the executable jar runs fine.
Most likely the problem is that you have the necessary libraries/APIs (i.e. the external jars) defined in Eclipse, but you are not referencing them when running the application externally. Thus when you run from Eclipse that library (and its classes) is included in your classpath, allowing the JVM to find all the required classes. However, when you are running externally, these additional external jars are not in your classpath (since Eclipse is not doing it for you). This is a potential danger when you test using an IDE; you have to figure out classpath issues when getting ready to deploy.
So you either need to:
Define all those external jars in your classpath when you run your application (via the -classpath option)
Create a Super Jar file by un-jar-ing all the external libraries, and then jar everything (including your code) into a single jar. (Be sure to read any license agreements for the external libraries to verify this is ok). You can use the Antjar task to do this for you. You'll want to leave the keepcompression option to its default value of false. There are some dangers to this including the loss of code signatures that are located in /META-INF/MANIFEST.MF files, the danger of overwriting files common to multiple libraries (such as README, license.txt, and log4j.properties to name a few), loss of digital signature if the third-party jar is signed, and if the third-party JAR contains JARs itself.
Package the external JARs in with your JAR (again you can use the Ant jar task, but set keepcompression to true) and then to load classes in JAR files within your JAR file into the class path, you must write custom code to load those classes.
Vote for this (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4648386) request for enhancement to Java so that the above option will happen automatically without the need for custom classloader code. Granted this would be a rather long term solution and there is debate as to whether this is a good idea since some developers argue that "a jar is suppose to be 'an atomic' entity which can be sealed and distributed." I haven't thought about it enough myself to form an opinion on the issue.