简体   繁体   中英

Programmatically creating jar file

I am running Mac OSX Mavericks. Right now I am creating a JAR file from a folder (org, the package). When I use this code from 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();
}
}

When I extract the JAR file, There is a META-INF folder, but instead of having the org folder in the extracted jar, I have my Users folder copied into it (except because of it's size, its wasn't filled with all my stuff and my application crashed). I'm expecting this is because the code was written for a Windows system, and the differences with the filesystem (such as \\ or /). How would I make the code include only the "org" directory, and not everything leading up to it?

Provided you use Java 7+ you may easily do this by using one of my packages in combination with the zip filesystem provider of the JDK to create it:

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM