以编程方式创建jar文件

时间:2015-03-05 16:32:16

标签: java macos jar

我正在运行Mac OSX Mavericks。现在我正在从文件夹(org,包)创建一个JAR文件。当我使用here中的代码时:

public void run() throws IOException
{
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
JarOutputStream target = new JarOutputStream(new FileOutputStream("/Users/username/Library/Application Support/VSE/temp/output.jar"), manifest);
add(new File("/Users/username/Library/Application Support/VSE/temp/org"), 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();
}
}

当我提取JAR文件时,有一个META-INF文件夹,但是我没有在提取的jar中使用org文件夹,而是将我的Users文件夹复制到其中(除非因为它的大小,它没有被填充)我所有的东西和我的应用程序崩溃了)。我期待这是因为代码是为Windows系统编写的,以及与文件系统的差异(例如\或/)。我如何使代码仅包含“org”目录,而不包括导致它的所有内容?

1 个答案:

答案 0 :(得分:0)

如果您使用Java 7+,您可以通过将one of my packages与JDK的zip文件系统提供程序结合使用来轻松完成此操作:

private static final Map<String, ?> ENV = Collections.singletonMap("create", "true");

public void run()
    throws IOException
{
    final Path zipPath = Paths.get("/Users/username/Library/Application Support/VSE/temp/output.jar");
    final Path srcdir = Paths.get("/Users/username/Library/Application Support/VSE/temp/org");
    final URI uri = URI.create("jar:" + zipPath.toUri());

    Files.deleteIfExists(zipPath);

    try (
        final FileSystem zipfs = FileSystems.newFileSystem(uri, ENV);
    ) {
        copyManifest(zipfs);
        copyDirectory(srcdir, zipfs);
    }
}

private void copyManifest(final FileSystem zipfs)
    throws IOException
{
    final Manifest manifest = new Manifest();
    manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
    Files.createDirectory(zipfs.getPath("META-INF/");

    try (
        final OutputStream out = Files.newOutputStream(zipfs.getPath("META-INF/MANIFEST.MF"));
    ) {
        manifest.write(out);
    }
}

private void copyDirectory(final Path srcdir, final FileSystem zipfs)
{
    final String lastName = srcdir.getFileName().toString();
    final Path dstDir = zipfs.getPath(lastName);
    Files.createDirectory(dstDir);
    MoreFiles.copyRecursive(srcDir, dstDir, RecursionMode.FAIL_FAST);
}