2016年4月6日 星期三

ADBException: Any type element type has not been given

這陣子在做API改寫時,我用了Dynamic Proxy Pattern統一處理了Service層級的API Response與Exception Handler。
現在的團隊使用Apache Axis2建立WebService,雖然使用的是WSDL、SOAP,但回傳的格式不是XML,而是JSON String,所以Service層的回傳型態都是String。
代理將Service Return的東西做了Object to Json String與外層格式的統一處理,所以Proxy實際回傳的是JSON String,Servcie的Impl回傳的東西可能是各種形態。因為Proxy與Implement回傳的型態是不同的,所以Service Interface的回傳型態必須改為Object
問題來了,Axis2 Service不能回傳Object型別,因為Axis2 adb有bug,ADB handles anyType
在使用Axis2 Code Generator Tool做WSDL2Java產生stub後,會看到只要回傳型態為Object時,(WSDL XML Return type就會是type:anyType),產生出來的stub code就會在API回傳的時候,試著要在回傳的XML資料內找到type,並嘗試將回傳資料轉型(ConverterUtil.getAnyTypeObject(...)),但是記得嗎??最一開始我就提到了,回傳的格式不是XML,而是JSON String,所以根本不會有type,在找不到type屬性的情況下CnverterUtil索性就丟了一個ADBException(as my title)。
Workaround的解法有兩種:
解法一,override ConverterUtil getAnyTypeObject Method,替換掉丟出異常的那一行
returnObject = xmlStreamReader.getElementText();

Java Exception

http://villebez.logdown.com/posts/2016/04/01/java-exception
java exception hierarchy
Exception Hierarchy DiagramException Hierarchy Diagram
圖片來源:http://java5tutor.info/java/flowcontrol/exceptionover.html

checked exceptions and unchecked exceptions

Use checked exceptions for recoverable conditions and runtime (unchecked) exceptions for programming errors.

checked Exception

程式如果違反handle-or-declare rule,將被Java Compiler視為『語法錯誤』,程式無法編譯成功。
handle-or-declare rule
  • Handle the exception by using the try-catch-finally block.
  • Declare that the code causes an exception by using the throws clause.

unchecked Exception

不需要補抓的錯誤,例如:RuntimeException、NullPointerException...等等

JAVA異常處理中的原則和建議

原則:不要忽略checked Exception

忽略可能導致兩個結果:
由於這裡的異常導致在程序中別的地方拋出一個異常,這種情況會使工程師在除錯時感到迷惑,因為新的異常拋出的地方並不是程式真正發生問題的地方,也不是發生問題的真正原因。
程序繼續運行,並得出一個錯誤的輸出結果,這種問題更加難以捕捉,因為很可能把它當成一個正確的輸出。

建議:不要捕獲unchecked Exception

Error
RuntimeException
ex:NullPointException, IndexOutofBoundsException
例外情況:Daemon Thread (長時間運行的背景程式)

原則:不要直接 catch 最上層的 Exception

不同Exception需要不同的處裡與恢復機制
可能拋出RuntimeException

原則:使用finally釋放資源

檔案串流,DB、Socket、FTP Connection

原則:finally不能拋出異常

會導致真正的異常訊息遺失

原則:拋出自定義異常時帶上原始異常訊息

new MyException(key+“:”+e.getMessage);
new MyException(key, e);

原則:print Exception Stack, not just message

原則:

If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.

怎麼做??