How to write a Java program which can extract a JAR file and store its data in specified directory (location)?

Viewed 78111

I have created a JAR file. Now, I created another Java program. I want to unpack that JAR file in some other directory, meaning I want to do something like unzip.

If I run jar -xf filename.jar this causes some error:

Exception in thread "main" java.io.IOException: Cannot run program "jar": 
java.io.IOException: error=2, No such file or directory
     at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
     at java.lang.Runtime.exec(Runtime.java:593)`
10 Answers

In case anyone is interested..

Here's a version for Java 7+ using buffered I/O and try-with-resources.

public static void unzip(File archive, File destDir) throws IOException {
    byte[] buffer = new byte[256 * 1024];
    destDir.mkdirs();
    try (JarFile jar = new JarFile(archive)) {
        Enumeration<JarEntry> entries = jar.entries();
        while (entries.hasMoreElements()) {
            JarEntry ent = entries.nextElement();
            File f = new File(destDir, ent.getName());
            if (ent.isDirectory()) {
                f.mkdir();
                continue;
            }
            try (InputStream is = jar.getInputStream(ent);
                 FileOutputStream os = new FileOutputStream(f)) {
                for (int r; (r = is.read(buffer)) > 0; ) {
                    os.write(buffer, 0, r);
                }
            }
        }
    }
}

Here's my version, using Java 8 and org.apache.commons.io Its work for me.

File userDir = new File("resources");
userDir.mkdir();
JarFile jar = new JarFile("123.jar");
jar.stream()
   .filter(file -> 
    file.getName().contains("BOOT-INF/classes") && !file.getName().contains("BOOT-INF/classes/ch/"))
   .peek(file -> {
File res = new File(userDir.getPath() + file.getName().replaceAll("BOOT-INF/classes", ""));

     if (file.isDirectory()) {
          res.mkdirs();
     } else { try {
                  FileUtils.copyInputStreamToFile(jar.getInputStream(file), res);
            } catch (IOException e) {
                  System.out.println(e.getMessage());
            }
     }
     }).forEach(file -> LOGGER.info("Extract file: " + file.getName()));
Related