The method works in reflection, but not in the “usual way” in Java

I have an exception when I execute this code:

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

And an exception:

 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) 

This exception is thrown when the code runs on an IBM machine, when it runs on a Windows machine, it runs correctly.

Examining this, I found that the return class for si.getDigestAlgoritmId() is different for IBM machines. For IBM, java is com.ibm.security.x509.AlgorithmId , and for java6 it is sun.security.x509.AlgorithmId . And both classes have a getName() method.

But the strangest thing is that if I call the method by reflection, the exception will not appear, and it works correctly in both environments. Can someone answer why it works this way?

I think the solution is to do it with reflection, but I would like to know the reason why this works with reflection, and in the usual way it is not. Basically, to avoid similar errors in the future.

Thanks in advance and sorry for my bad english.

Edit: Call reflection:

 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){...} 
+6
source share
1 answer

SignerInfo.getDigestAlgoritmId() has different declarations in these two versions of Java. If you compile your class with one declaration, it will not work with another. The type is stored in your .class file and must match at runtime.

If you use reflection, you do not need to getDigestAlgoritmId at compile time. It will work with any ad if it matches the specified name and parameters.

Be careful with reflection. sun.security.x509.AlgorithmId does not seem to be part of the public Java API. It may differ from versions and suppliers. These two differ only in return types. Who knows what differences exist in other Java implementations. If possible, stick with the official Java API.

+2
source

Source: https://habr.com/ru/post/919254/


All Articles