如何使用JarOutputStream来创build一个JAR文件?

如何使用java.util.jar.JarOutputStream编程方式创buildJAR文件? 由我的程序产生的JAR文件看起来是正确的(它提取罚款),但是当我尝试从它加载一个库Java抱怨,它找不到明确存储在其中的文件。 如果我解压缩JAR文件并使用Sun的jar命令行工具重新压缩它,则生成的库工作正常。 总之,我的JAR文件有些问题。

请解释如何以编程方式创buildJAR文件,并使用清单文件完成。

事实certificate, JarOutputStream有三个无证的怪癖:

  1. 目录名称必须以'/'斜线结尾。
  2. path必须使用“/”斜杠,而不是“\”
  3. 条目不能以“/”斜杠开始。

这是创buildJar文件的正确方法:

 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 { BufferedInputStream in = null; try { if (source.isDirectory()) { String name = source.getPath().replace("\\", "/"); if (!name.isEmpty()) { 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); return; } JarEntry entry = new JarEntry(source.getPath().replace("\\", "/")); entry.setTime(source.lastModified()); target.putNextEntry(entry); 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(); } finally { if (in != null) in.close(); } } 

还有另外一个“怪癖”要注意:所有JarEntry的名字不应该以“/”开头。

例如:清单文件的jar条目名称是“META-INF / MANIFEST.MF”而不是“/META-INF/MANIFEST.MF”。

所有jar条目都应遵循相同的规则。

以下是使用JarOutputStream创buildJAR文件的示例代码:

你可以用这个代码来做到这一点:

 public void write(File[] files, String commment) throws IOException { FileOutputStream fos = new FileOutputStream(PATH + FILE); JarOutputStream jos = new JarOutputStream(fos, manifest); BufferedOutputStream bos = new BufferedOutputStream(jos); jos.setComment(commment); for (File f : files) { print("Writing file: " + f.toString()); BufferedReader br = new BufferedReader(new FileReader(f)); jos.putNextEntry(new JarEntry(f.getName())); int c; while ((c = br.read()) != -1) { bos.write(c); } br.close(); bos.flush(); } bos.close(); // JarOutputStream jor = new JarOutputStream(new FileOutputStream(PATH + FILE), manifest); } 

PATHvariables:JAR文件的path

FILEvariables:名称和格式

否则,你可以使用java.lang.Runtime类来做到这一点。
该类支持在cmd中运行的命令。
但是它可以抛出java.io.IOException
代码做到这一点:

 String files, jarFile; try { Runtime.getRuntime().exec("jar cvf "+jarFile+" "+files); } catch (java.io.IOException e) { e.printStackTrace(); }