2012-06-28 9 views
6

Mam wyjątek podczas I wykonanie tego kodu:metoda działa w refleksji, ale nie w sposób „normalny” w Javie

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

i wyjątek jest:

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) 

ten wyjątek jest generowany, gdy kod jest wykonywany na maszynie IBM, gdy jest wykonywany na komputerze z systemem Windows, który działa poprawnie.

Badanie tego dowiedziałem się, że klasa zwrotu dla si.getDigestAlgoritmId() jest inna dla maszyn IBM. Dla java IBM jest to com.ibm.security.x509.AlgorithmId, a dla java6 jest to sun.security.x509.AlgorithmId. Obie klasy mają metodę getName().

Ale najdziwniejsze jest to, że jeśli wywołam tę metodę przez odbicie, wyjątek się nie pojawia i działa poprawnie w obu środowiskach. Czy ktoś może odpowiedzieć, dlaczego działa w ten sposób?

Myślę, że rozwiązaniem jest zrobienie tego z refleksją, ale chciałbym poznać powód, dla którego z refleksją działa i normalny sposób nie działa. Głównie, aby uniknąć podobnych błędów w przyszłości.

Z góry dziękuję i przepraszam za mój zły angielski.

Edit: Wywołanie refleksji:

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

Byłoby dobrze, gdyby dodać sposób wywołania metody za pomocą refleksji. –

Odpowiedz

2

SignerInfo.getDigestAlgoritmId() ma różne deklaracje w tych dwóch wersjach Java. Jeśli skompilujesz swoją klasę za pomocą jednej deklaracji, nie będzie ona działać z drugą. Typ jest przechowywany w pliku .class i musi pasować podczas uruchamiania.

Jeśli używasz refleksji, nie potrzebujesz deklaracji getDigestAlgoritmId podczas kompilacji. Będzie działać z każdą deklaracją, o ile pasuje do podanej nazwy i parametrów.

Uważaj na odbicie. sun.security.x509.AlgorithmId nie wydaje się być częścią publicznego interfejsu API języka Java. Może się różnić między wersjami i dostawcami. Te dwa różnią się tylko typami powrotów. Kto wie, jakie są różnice w innych implementacjach Javy. Jeśli to możliwe, trzymaj się oficjalnego API Java.

Powiązane problemy