6

そのため、mainfest ファイルのいくつかの値をチェックして、.jar が有効かどうかを確認しようとしています。javaを使用してファイルを読み取って解析する最良の方法は何ですか? このコマンドを使用してファイルを抽出することを考えました

jar -xvf anyjar.jar META-INF/MANIFEST.MF

しかし、私は次のようなことをすることができます:

File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF");

次に、バッファリングされたリーダーなどを使用して、ファイルの行を解析しますか?

助けてくれてありがとう...

4

3 に答える 3

12

このツールを使用する際の問題jarは、完全な JDK をインストールする必要があることです。Java の多くのユーザーは、JRE のみをインストールしますが、これには は含まれていませんjar

また、jarユーザーの PATH 上にある必要があります。

代わりに、次のような適切な API を使用することをお勧めします。

Manifest m = new JarFile("anyjar.jar").getManifest();

それは実際にはもっと簡単なはずです!

于 2013-10-13T15:51:15.220 に答える
5

java.lang.Packageの Package クラスには、必要なことを行うためのメソッドがあります。Java コードを使用してマニフェスト コンテンツを取得する簡単な方法を次に示します。

String t = this.getClass().getPackage().getImplementationTitle();
String v = this.getClass().getPackage().getImplementationVersion();

これを共有ユーティリティ クラスの静的メソッドに入れました。このメソッドは、クラス ハンドル オブジェクトをパラメーターとして受け入れます。このようにして、システム内のどのクラスも、必要なときに独自のマニフェスト情報を取得できます。明らかに、値の配列またはハッシュマップを返すようにメソッドを簡単に変更できます。

メソッドを呼び出します。

    String ver = GeneralUtils.checkImplVersion(this);

GeneralUtils.javaというファイルのメソッド:

public static String checkImplVersion(Object classHandle)
{
   String v = classHandle.getClass().getPackage().getImplementationVersion();
   return v;
}

また、Package クラス (独自の Build-Date など) を介して取得できるもの以外のマニフェスト フィールド値を取得するには、Main Attibutes を取得し、それらを処理して、必要な特定のものを求めます。この次のコードは、おそらくSOで見つけた同様の質問からのわずかな変更です。(クレジットしたいのですが、紛失してしまいました。申し訳ありません。)

これを try-catch ブロックに入れて、classHandle (「this」または MyClass.class ) をメソッドに渡します。「classHandle」はクラス型です:

  String buildDateToReturn = null;
  try
  {
     String path = classHandle.getProtectionDomain().getCodeSource().getLocation().getPath();
     JarFile jar = new JarFile(path);  // or can give a File handle
     Manifest mf = jar.getManifest();
     final Attributes mattr = mf.getMainAttributes();
     LOGGER.trace(" --- getBuildDate: "
           +"\n\t path:     "+ path
           +"\n\t jar:      "+ jar.getName()
           +"\n\t manifest: "+ mf.getClass().getSimpleName()
           );

     for (Object key : mattr.keySet()) 
     {
        String val = mattr.getValue((Name)key);
        if (key != null && (key.toString()).contains("Build-Date"))
        {
           buildDateToReturn = val;
        }
     }
  }
  catch (IOException e)
  { ... }

  return buildDateToReturn;
于 2014-04-24T21:58:55.370 に答える
3

最も簡単な方法は、JarURLConnection クラスを使用することです。

String className = getClass().getSimpleName() + ".class";
String classPath = getClass().getResource(className).toString();
if (!classPath.startsWith("jar")) {
    return DEFAULT_PROPERTY_VALUE;
}

URL url = new URL(classPath);
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
Manifest manifest = jarConnection.getManifest();
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue(PROPERTY_NAME);

...class.getProtectionDomain().getCodeSource().getLocation();でパスを与える場合があるためvfs:/、これは追加で処理する必要があります。

または、ProtectionDomain を使用して:

File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
if (file.isFile()) {
    JarFile jarFile = new JarFile(file);
    Manifest manifest = jarFile.getManifest();
    Attributes attributes = manifest.getMainAttributes();
    return attributes.getValue(PROPERTY_NAME);
}
于 2016-02-17T11:56:31.013 に答える