Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JarOutputStream to create a JAR file?

Tags:

java

jar

How does one create a JAR file programmatically using java.util.jar.JarOutputStream? The JAR file produced by my program looks correct (it extracts fine) but when I try loading a library from it Java complains that it cannot find files which are clearly stored inside it. If I extract the JAR file and use Sun's jar command-line tool to re-compress it the resulting library works fine. In short, something is wrong with my JAR file.

Please explain how to create a JAR file programmatically, complete with a manifest file.

like image 857
Gili Avatar asked Aug 15 '09 05:08

Gili


People also ask

How can you create your own JAR file?

First create your java file as you require. Right click your project -> click on export -> select option jar, follow the dialog box. Now, you have created your own java jar file. Create your new project as you require, import that jar file as you are importing other jar files.

How do I manually create an executable JAR file?

In Eclipse you can do it simply as follows : Right click on your Java Project and select Export. Select Java -> Runnable JAR file -> Next.

Which tool is used for creating JAR file for table?

We can imagine a . jar file as a zipped file(. zip) that is created by using WinZip software.


2 Answers

It turns out that JarOutputStream has three undocumented quirks:

  1. Directory names must end with a '/' slash.
  2. Paths must use '/' slashes, not '\'
  3. Entries may not begin with a '/' slash.

Here is the correct way to create a Jar file:

public void run() throws IOException {     Manifest manifest = new Manifest();     manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");     JarOutputStream target = new JarOutputStream(new FileOutputStream("output.jar"), manifest);     add(new File("inputDirectory"), target);     target.close(); }  private void add(File source, JarOutputStream target) throws IOException {     String name = source.getPath().replace("\\", "/");     if (source.isDirectory()) {         if (!name.endsWith("/")) {             name += "/";         }         JarEntry entry = new JarEntry(name);         entry.setTime(source.lastModified());         target.putNextEntry(entry);         target.closeEntry();         for (File nestedFile : source.listFiles()) {             add(nestedFile, target);         }     } else {         JarEntry entry = new JarEntry(name);         entry.setTime(source.lastModified());         target.putNextEntry(entry);         try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(source))) {             byte[] buffer = new byte[1024];             while (true) {                 int count = in.read(buffer);                 if (count == -1)                     break;                 target.write(buffer, 0, count);             }             target.closeEntry();         }     } } 
like image 104
Gili Avatar answered Sep 19 '22 21:09

Gili


There's another "quirk" to pay attention: All JarEntry's names should NOT begin with "/".

For example: The jar entry name for the manifest file is "META-INF/MANIFEST.MF" and not "/META-INF/MANIFEST.MF".

The same rule should be followed for all jar entries.

like image 40
Hélio Luiz Alves Rodrigues Avatar answered Sep 21 '22 21:09

Hélio Luiz Alves Rodrigues