Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java Tip 127: See JAR run

Enable your unrunnable JARs to run with the java -jar command

  • Print
  • Feedback

Page 2 of 2

    Attributes a = manifest.getMainAttributes();
    String oldMainClass = a.putValue("Main-Class", args[1]);
    //If an old value exists, tell the user and exit
    if (oldMainClass != null) {
        System.out.println("Warning: old Main-Class value is: "
                           + oldMainClass);
        System.exit(1);
    }


Output the new JAR

We need to create a new jar file, so we must use the JarOutputStream class. Note: We must ensure we don't use the same file for output as we do for input. Alternatively, perhaps the program should consider the case where the two jar files are the same and prompt the user if he wishes to overwrite the original. However, I reserve this as an exercise for the reader. On with the code!

    System.out.println("Writing to " + args[2] + "...");
    JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]),
                                                 manifest);


We must write every entry from the input JAR to the output JAR, so iterate over the entries:

    //Create a read buffer to transfer data from the input
    byte[] buf = new byte[4096];
    //Iterate the entries
    JarEntry entry;
    while ((entry = jarIn.getNextJarEntry()) != null) {
        //Exclude the manifest file from the old JAR
        if ("META-INF/MANIFEST.MF".equals(entry.getName())) continue;
        //Write the entry to the output JAR
        jarOut.putNextEntry(entry);
        int read;
        while ((read = jarIn.read(buf)) != -1) {
            jarOut.write(buf, 0, read);
        }
        jarOut.closeEntry();
    }
    //Flush and close all the streams
    jarOut.flush();
    jarOut.close();
    jarIn.close();


Complete program

Of course, we must place this code inside a main method, inside a class, and with a suitable set of import statements. The Resources section provides the complete program.

Usage example

Let's put this program to use with an example. Suppose you have an application whose main entry point is in a class called HelloRunnableWorld. (This is the full class name.) Also assume that you've created a JAR called myjar.jar, containing the entire application. Run MakeJarRunnable on this jar file like so:

    java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar


Again, as mentioned earlier, notice how I order the argument list. If you forget the order, just run this program with no arguments and it will respond with a usage message.

Try to run the java -jar command on myjar.jar and then on myjar_r.jar. Note the difference! After you've done that, explore the manifest files (META-INF/MANIFEST.MF) in each JAR. (You can find both JARs in the source code.)

Here's a suggestion: Try to make the MakeJarRunnable program into a runnable JAR!

Run with it

Running a JAR by double-clicking it or using a simple command is always more convenient than having to include it in your classpath and running a specific main class. To help you do this, the JAR specification provides a Main-Class attribute for the JAR's manifest file. The program I present here lets you utilize Java's JAR API to easily manipulate this attribute and make your JARs runnable.

About the author

Shawn Silverman is currently a graduate student in the department of electrical and computer engineering at the University of Manitoba in Canada. He started working with Java in mid-1996, and has been using it almost exclusively ever since. His current interests include the simulation of electric fields and fluids, error-correcting codes, and the implementation of nifty GUI (graphical user interface) tricks. Shawn also teaches a third-year software design course in the computer engineering department at his university.
  • Print
  • Feedback

Resources