简体   繁体   English

以编程方式创建jar文件

[英]Programmatically creating jar file

I am running Mac OSX Mavericks. 我正在运行Mac OSX Mavericks。 Right now I am creating a JAR file from a folder (org, the package). 现在,我正在从一个文件夹(组织,包)创建一个JAR文件。 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). 当我提取JAR文件时,有一个META-INF文件夹,但是没有将org文件夹放在提取的jar中,而是将我的Users文件夹复制到了其中(除了因为它的大小,它没有被我所有的文件填充)东西和我的应用程序崩溃了)。 I'm expecting this is because the code was written for a Windows system, and the differences with the filesystem (such as \\ or /). 我期望这是因为代码是为Windows系统编写的,并且与文件系统(例如\\或/)不同。 How would I make the code include only the "org" directory, and not everything leading up to it? 如何使代码仅包含“ org”目录,而不包含导致该目录的所有内容?

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: 如果您使用Java 7+,则可以通过将我的一个软件包与JDK的zip文件系统提供程序结合使用来轻松地创建Java 7:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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