如何使用java.util.jar.JarOutputStream
以编程方式创建JAR文件?我的程序生成的JAR文件看起来是正确的(它提取的很好),但是当我尝试从它加载一个库时,Java抱怨它找不到明确存储在其中的文件。如果我解压缩JAR文件并使用Sun的jar
命令行工具重新压缩它,则生成的库工作正常。总之,我的JAR文件出了问题。如何使用JarOutputStream创建JAR文件?
请解释如何以编程方式创建JAR文件,并附带清单文件。
如何使用java.util.jar.JarOutputStream
以编程方式创建JAR文件?我的程序生成的JAR文件看起来是正确的(它提取的很好),但是当我尝试从它加载一个库时,Java抱怨它找不到明确存储在其中的文件。如果我解压缩JAR文件并使用Sun的jar
命令行工具重新压缩它,则生成的库工作正常。总之,我的JAR文件出了问题。如何使用JarOutputStream创建JAR文件?
请解释如何以编程方式创建JAR文件,并附带清单文件。
事实证明,JarOutputStream
有三个无证的怪癖:
下面是创建一个JAR文件的正确方法:
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();
}
}
这些'怪癖'实际上是zip规范的一部分(jar文件只是带有清单和不同扩展名的zip文件)。我同意它应该记录在API文档中,但是 - 我建议打开一个问题(http://bugs.sun.com/bugdatabase/) – 2009-08-15 19:18:03
更重要的是,API应该可以防止你通过创建无效的ZIP/JAR文件如果您传递了错误类型的斜杠或自动转换它们,则抛出异常。对于以斜线结尾的目录,由于无法自动纠正,所以应该记录它。我提交了一个错误报告,但尚未被接受。 – Gili 2009-08-16 15:52:38
经典的Sun/Oracle。关闭为“不是bug”:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6873352 – Gili 2012-01-17 18:06:13
下面是一些示例代码使用的JarOutputStream创建一个JAR文件:
还有一个“怪癖”注意:所有的JarEntry的名字不应该与“/”开头。
例如:清单文件的jar条目名称是“META-INF/MANIFEST.MF”,而不是“/META-INF/MANIFEST.MF”。
所有jar条目都应遵循相同的规则。
您可以使用此代码做到这一点:
public void write(File[] files, String comment) throws IOException {
FileOutputStream fos = new FileOutputStream(PATH + FILE);
JarOutputStream jos = new JarOutputStream(fos, manifest);
BufferedOutputStream bos = new BufferedOutputStream(jos);
jos.setComment(comment);
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);
}
PATH
变量:路径JAR文件
FILE
变量:名称和格式
也许你应该表现出你目前(非工作)解决方案 – ChssPly76 2009-08-15 06:14:35