Knight of Ni
Knight of Ni

Reputation: 1830

Unpacking / extracting resource from another JAR file

I have two jar files. Normally if I want to 'unpack' resource from my jar file I go for :

    InputStream in = MyClass.class.getClassLoader().getResourceAsStream(name);
    byte[] buffer = new byte[1024];
    int read = -1;
    File temp2 = new File(new File(System.getProperty("user.dir")), name);
    FileOutputStream fos2 = new FileOutputStream(temp2);

    while((read = in.read(buffer)) != -1) {
        fos2.write(buffer, 0, read);
    }
    fos2.close();
    in.close();

What If I would have another JAR files in the same directory? Can I access the second JAR file resources in simillar way? This second JAR is not runned so don't have own class loader. Is the only way to unzip this second JAR file?

Upvotes: 2

Views: 1108

Answers (3)

Sergey Morozov
Sergey Morozov

Reputation: 4608

You can use URLClassLoader.

URLClassLoader classLoader = new URLClassLoader(new URL[]{new URL("path_to_file//myjar.jar")})
classLoader.loadClass("MyClass");//is requared
InputStream stream = classLoader.getResourceAsStream("myresource.properties");

Upvotes: 1

Karthik
Karthik

Reputation: 1023

I've used the below mentioned code to do the same kind of operation. It uses JarFile class to do the same.

      /**
   * Copies a directory from a jar file to an external directory.
   */
  public static void copyResourcesToDirectory(JarFile fromJar, String jarDir, String destDir)
      throws IOException {
    for (Enumeration<JarEntry> entries = fromJar.entries(); entries.hasMoreElements();) {
      JarEntry entry = entries.nextElement();
      if (entry.getName().startsWith(jarDir + "/") && !entry.isDirectory()) {
        File dest = new File(destDir + "/" + entry.getName().substring(jarDir.length() + 1));
        File parent = dest.getParentFile();
        if (parent != null) {
          parent.mkdirs();
        }

        FileOutputStream out = new FileOutputStream(dest);
        InputStream in = fromJar.getInputStream(entry);

        try {
          byte[] buffer = new byte[8 * 1024];

          int s = 0;
          while ((s = in.read(buffer)) > 0) {
            out.write(buffer, 0, s);
          }
        } catch (IOException e) {
          throw new IOException("Could not copy asset from jar file", e);
        } finally {
          try {
            in.close();
          } catch (IOException ignored) {}
          try {
            out.close();
          } catch (IOException ignored) {}
        }
      }
    }

Upvotes: 2

rolfl
rolfl

Reputation: 17707

If the other Jar is in your regular classpath then you can simply access the resource in that jar in the exact same way. If the Jar is just an file that's not on your classpath you will have to instead open it and extract the file with the JarFile and related classes. Note that Jar files are just special types of Zip files, so you can also access a Jar file with the ZipFile related classes

Upvotes: 1

Related Questions