2012-06-28 19 views
6

Tôi đã có một ngoại lệ trong khi tôi thực thi mã này:Phương pháp làm việc trong suy nghĩ nhưng không trong "cách bình thường" trong Java

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

Và ngoại trừ là:

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) 

này ngoại lệ được ném khi mã được thực thi trên máy IBM, khi nó được thực thi trên máy Windows, nó hoạt động chính xác.

Nghiên cứu điều này, tôi đã phát hiện ra rằng lớp trả về cho si.getDigestAlgoritmId() là khác nhau đối với các máy IBM. Đối với java của IBM nó là com.ibm.security.x509.AlgorithmId và đối với java6 nó là sun.security.x509.AlgorithmId. Và cả hai lớp đều có phương thức getName().

Nhưng điều lạ lùng nhất là nếu tôi gọi phương thức bằng cách phản ánh ngoại lệ không xuất hiện và nó hoạt động chính xác trong cả hai môi trường. Ai đó có thể trả lời tại sao nó hoạt động theo cách này?

Tôi nghĩ rằng giải pháp là để làm điều đó với sự phản ánh, nhưng tôi muốn biết lý do tại sao với sự phản ánh nó hoạt động và cách bình thường nó không. Chủ yếu là để tránh những sai lầm tương tự trong tương lai.

Cảm ơn trước và xin lỗi vì tiếng Anh không tốt của tôi.

Edit: Cuộc gọi phản ánh:

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

Sẽ tốt hơn nếu bạn thêm cách bạn gọi phương thức bằng cách sử dụng phản chiếu. –

Trả lời

2

SignerInfo.getDigestAlgoritmId() có tờ khai khác nhau trong hai phiên bản Java. Nếu bạn biên dịch lớp của bạn với một khai báo, nó sẽ không hoạt động với lớp khác. Loại được lưu trữ trong tệp .class của bạn và phải khớp với lúc chạy.

Nếu bạn sử dụng phản chiếu, bạn không cần khai báo getDigestAlgoritmId lúc biên dịch. Nó sẽ làm việc với bất kỳ khai báo nào, miễn là nó khớp với tên và các tham số bạn đã chỉ định.

Hãy cẩn thận với sự phản chiếu. sun.security.x509.AlgorithmId dường như không phải là một phần của API java công khai. Nó có thể khác nhau giữa các phiên bản và nhà cung cấp. Hai loại này chỉ khác nhau về các loại trả về. Ai biết được sự khác biệt nào trong các triển khai Java khác. Nếu có thể, hãy liên kết với API Java chính thức.