2012-06-28 9 views
6

で「通常の方法」で、私はこのコードを実行しながら、私は例外を持っていません:方法は、反射で動作しますが、Java

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){...} 
+1

リフレクションを使用してメソッドを呼び出す方法を追加するとよいでしょう。 –

答えて

2

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

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

反射に注意してください。 sun.security.x509.AlgorithmIdはパブリックJava APIの一部ではないようです。バージョンとベンダーによって異なる場合があります。これらの2つはリターンタイプでのみ異なります。他のJava実装にどのような違いがあるかは誰に分かりますか。可能であれば、公式のJava APIを使用してください。