6

このコードの実行中に例外が発生しました。

p7 = new PKCS7(p7byte);
...
SignerInfo si = p7.getSignerInfos()[0];
String name = si.getDigestAlgorithmId().getName();

例外は次のとおりです。

Exception in thread "main" java.lang.NoSuchMethodError: sun/security/pkcs/SignerInfo.getDigestAlgorithmId()Lsun/security/x509/AlgorithmId;
        at reflex.Reflex.testPKCS7(Reflex.java:151)
        at reflex.Reflex.main(Reflex.java:43)

この例外は、コードが IBM マシンで実行されるとスローされ、Windows マシンで実行されると正常に動作します。

si.getDigestAlgoritmId()これを調べたところ、 IBM マシンの戻りクラスが異なることがわかりました。IBM の Java の場合はcom.ibm.security.x509.AlgorithmIdであり、java6 の場合はsun.security.x509.AlgorithmIdです。そして、両方のクラスにgetName()メソッドがあります。

しかし、最も奇妙なことは、リフレクションによってメソッドを呼び出すと、例外が表示されず、両方の環境で正しく動作することです。なぜこのように機能するのか、誰かが答えることができますか?

解決策はリフレクションで行うことだと思いますが、リフレクションで機能する理由と、通常は機能しない理由を知りたいです。主に、将来同様の間違いを避けるためです。

事前に感謝し、私の下手な英語で申し訳ありません.

編集:リフレクションコール:

try{
  Class clase = si.getClass();
  Method metodo = clase.getMethod("getDigestAlgorithmId");
  Object result = metodo.invoke(si,null); 
  System.out.println("Result.class=" + result.getClass().getName());
  System.out.println("Result=" + result);
}catch(Exception e){...}
4

1 に答える 1

2

SignerInfo.getDigestAlgoritmId()は、これら 2 つの Java バージョンで異なる宣言をしています。クラスを 1 つの宣言でコンパイルすると、他の宣言では機能しません。タイプは.classファイルに保存され、実行時に一致する必要があります。

リフレクションを使用する場合、getDigestAlgoritmIdコンパイル時の宣言は必要ありません。指定した名前とパラメーターに一致する限り、どの宣言でも機能します。

反射には気をつけてください。sun.security.x509.AlgorithmIdpublic Java API の一部ではないようです。バージョンやベンダーによって異なる場合があります。これら 2 つの違いは、戻り値の型だけです。他の Java 実装にどのような違いがあるかは誰にもわかりません。可能であれば、公式の Java API を使用してください。

于 2012-06-28T15:29:05.653 に答える