JarFile from inside * .jar or input stream to file?

I have a can or war.

I program by reading this jar, and when I find a jar inside this jar, I would like to programmatically read it again.

But JarFile provides only getInputStream, which I cannot pass to the constructor of JarFile (File file).

How to read a jar from a jar?

EDIT: I was thinking about getting the file somehow from the loader class or something.

+3
source share
4 answers

you can create a jar file in the file system, something like

File tempFile=TempFile.createFile("newJar",".jar"); 

and write a stream to it. After that, you can create your JarFile (tempFile) and process it ...

Forget it if the program works as an unsigned applet / JNLP, since you do not have the right to create a file in the file system ...

+1
source

Update: Sorry, it's probably too late for your needs, I just noticed your last question in the comments. Therefore, I modified the example to show that each nested record is copied directly to the OutputStream without the need to inflate an external can.

In this case, OutputStream is System.out , but can be any OutputStream (for example, a file ...).


No need to use a temporary file. You can use a JarInputStream instead of a JarFile , pass an InputStream from an external record to the constructor, and then you can read the contents of the flag.

For instance:

 JarFile jarFile = new JarFile(warFile); Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = (JarEntry) entries.nextElement(); if (jarEntry.getName().endsWith(".jar")) { JarInputStream jarIS = new JarInputStream(jarFile .getInputStream(jarEntry)); // iterate the entries, copying the contents of each nested file // to the OutputStream JarEntry innerEntry = jarIS.getNextJarEntry(); OutputStream out = System.out; while (innerEntry != null) { copyStream(jarIS, out, innerEntry); innerEntry = jarIS.getNextJarEntry(); } } } ... /** * Read all the bytes for the current entry from the input to the output. */ private void copyStream(InputStream in, OutputStream out, JarEntry entry) throws IOException { byte[] buffer = new byte[1024 * 4]; long count = 0; int n = 0; long size = entry.getSize(); while (-1 != (n = in.read(buffer)) && count < size) { out.write(buffer, 0, n); count += n; } } 
+6
source

This is usually a matter of accessing an InputStream, and then working with it. This allows you to ignore most of the problems of "jar in jar on web server" and the like.

Apparently in this case it is JarFile.getInputStream () and JarInputStream ().

0
source

Recursively using JarFile again to read the new jar file. For instance,

 import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; public class JarReader { public static void readJar(String jarName) throws IOException { String dir = new File(jarName).getParent(); JarFile jf = new JarFile(jarName); Enumeration<JarEntry> en = jf.entries(); while(en.hasMoreElements()) { ZipEntry ze = (ZipEntry)en.nextElement(); if(ze.getName().endsWith(".jar")) { readJar(dir + System.getProperty("file.separator") + ze.getName()); } else { InputStream is = jf.getInputStream(ze); // ... read from input stream is.close(); System.out.println("Processed class: " + ze.getName()); } } } public static void main(String[] args) throws IOException { readJar(args[0]); } } 
-one
source

All Articles