web-dev-qa-db-ja.com

JarOutputStreamを使用してJARファイルを作成する方法は?

Java.util.jar.JarOutputStreamを使用してプログラムでJARファイルを作成するにはどうすればよいですか?私のプログラムによって生成されたJARファイルは正しいように見えます(正常に抽出されます)が、そこからライブラリをロードしようとすると、Javaは、その中に明確に保存されたファイルを見つけることができないと文句を言います。 JARファイルを作成し、Sunのjarコマンドラインツールを使用して再圧縮すると、結果のライブラリが正常に機能します。

マニフェストファイルを使用して、プログラムでJARファイルを作成する方法を説明してください。

53
Gili

JarOutputStreamには、文書化されていない3つの癖があります。

  1. ディレクトリ名は「/」スラッシュで終わる必要があります。
  2. パスには「\」ではなく「/」スラッシュを使用する必要があります
  3. エントリは「/」スラッシュで始めることはできません。

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();
  }
}
93
Gili

注意を払うべき別の「癖」があります:すべての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変数:名前と形式

2
Muskovets

JarOutputStreamを使用してJARファイルを作成するためのサンプルコードを次に示します。

2
ars