2012-06-28 11 views
6

Tengo una excepción mientras ejecuta este código:método funciona en la reflexión, pero no en "modo normal" en Java

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

y la excepción es:

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) 

Este Se lanza una excepción cuando el código se ejecuta en una máquina IBM, cuando se ejecuta en una máquina con Windows funciona correctamente.

Investigando esto, descubrí que la clase de devolución para si.getDigestAlgoritmId() es diferente para máquinas IBM. Para Java de IBM es com.ibm.security.x509.AlgorithmId y para java6 es sun.security.x509.AlgorithmId. Y ambas clases tienen un método getName().

Pero lo más extraño es que si llamo al método por reflexión, la excepción no aparece y funciona correctamente en ambos entornos. ¿Alguien puede responder por qué funciona de esta manera?

Creo que la solución es hacerlo con reflexión, pero me gustaría saber el motivo por el que con la reflexión funciona y de la manera normal no funciona. Principalmente para evitar errores similares en el futuro.

Gracias de antemano y disculpe por mi mal inglés.

Editar: La llamada reflexión:

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

Sería bueno si agrega cómo llama al método utilizando la reflexión. –

Respuesta

2

SignerInfo.getDigestAlgoritmId() tiene diferentes declaraciones de esos dos versiones de Java. Si compila su clase con una declaración, no funcionará con la otra. El tipo se almacena en su archivo .class y tiene que coincidir en tiempo de ejecución.

Si utiliza el reflejo, no necesita la declaración de getDigestAlgoritmId en tiempo de compilación. Funcionará con cualquier declaración, siempre y cuando coincida con el nombre y los parámetros que especificó.

Tenga cuidado con la reflexión. sun.security.x509.AlgorithmId no parece ser parte de la API pública de Java. Puede diferir entre las versiones y los proveedores. Esos dos difieren solo en los tipos de devolución. Quién sabe qué diferencias hay en otras implementaciones de Java. Si es posible, adhiérase a la API oficial de Java.

Cuestiones relacionadas