問題
如下所示,exception.getMessage() 輸出的信息帶上了Class name。這樣就會一直攜帶,看着不太舒服。
com.xxx.api.RealTimeException: com.xxx.api.RealTimeException: scp: SNAPHOT.jar: Permission denied
分析
這個類名應該來自於exception的轉換 嵌套
這里日志打印出來是 java.util.concurrent.ExecutionException 異常攜帶的信息。
那么java.util.concurrent.ExecutionException 這個異常是來自於Future。
可以看到 Future.get 調用了report,這里會處理異常。
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
再順着 new ExecutionException構造器,一直找到 Throwable的構造器
public Throwable(Throwable cause) {
fillInStackTrace();
detailMessage = (cause==null ? null : cause.toString());
this.cause = cause;
}
這里就很顯然,如果Exception子類使用 這個構造器,那么detailMessage 會取上一個 exception的.toString。而不是getMessage:
//Throwable
public String toString() {
String s = getClass().getName();
String message = getLocalizedMessage();
return (message != null) ? (s + ": " + message) : s;
}
解決
如果是ExecutionException異常,則取cause的Message,就不會有類名。這里假設cause 類是一個沒有再包裹其他exception的直接異常。
一般Exception的 message本身就不會帶有類名,子類也不會有。
try {
future.get();
} catch (Exception e) {
if (e instanceof ExecutionException) {
e = (Exception) e.getCause();
}
throw new RealTimeException(-1, e.getMessage());
}