Author: dkulp Date: Fri Mar 9 19:52:59 2012 New Revision: 1299008 URL: http://svn.apache.org/viewvc?rev=1299008&view=rev Log: Merged revisions 1299004 via svn merge from https://svn.apache.org/repos/asf/cxf/branches/2.5.x-fixes
........ r1299004 | dkulp | 2012-03-09 14:50:00 -0500 (Fri, 09 Mar 2012) | 10 lines Merged revisions 1298998 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/trunk ........ r1298998 | dkulp | 2012-03-09 14:32:02 -0500 (Fri, 09 Mar 2012) | 3 lines [CXF-4169] make nested exception causes available at the client Patch from Stefan Wachter applied ........ ........ Modified: cxf/branches/2.4.x-fixes/ (props changed) cxf/branches/2.4.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java Propchange: cxf/branches/2.4.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.4.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java?rev=1299008&r1=1299007&r2=1299008&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java (original) +++ cxf/branches/2.4.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java Fri Mar 9 19:52:59 2012 @@ -233,6 +233,7 @@ public class ClientFaultConverter extend } private void setStackTrace(Fault fault, Message msg) { + Throwable cause = null; Map<String, String> ns = new HashMap<String, String>(); XPathUtils xu = new XPathUtils(ns); ns.put("s", Fault.STACKTRACE_NAMESPACE); @@ -244,23 +245,50 @@ public class ClientFaultConverter extend while (st.hasMoreTokens()) { String oneLine = st.nextToken(); if (oneLine.startsWith("Caused by:")) { - // need to skip this part of message, - // as we can't create the cause exception instance directly. + cause = getCause(st, oneLine); break; } - StringTokenizer stInner = new StringTokenizer(oneLine, "!"); - StackTraceElement ste = new StackTraceElement(stInner.nextToken(), stInner.nextToken(), - stInner.nextToken(), Integer.parseInt(stInner.nextToken())); - stackTraceList.add(ste); + stackTraceList.add(parseStackTrackLine(oneLine)); } - if (stackTraceList.size() > 0) { - StackTraceElement[] stackTraceElement = new StackTraceElement[stackTraceList.size()]; + if (stackTraceList.size() > 0 || cause != null) { Exception e = msg.getContent(Exception.class); - e.setStackTrace(stackTraceList.toArray(stackTraceElement)); + if (!stackTraceList.isEmpty()) { + StackTraceElement[] stackTraceElement = new StackTraceElement[stackTraceList.size()]; + e.setStackTrace(stackTraceList.toArray(stackTraceElement)); + } + if (cause != null) { + e.initCause(cause); + } } } } + + // recursively parse the causes and instantiate corresponding throwables + private Throwable getCause(StringTokenizer st, String firstLine) { + // The actual exception class of the cause might be unavailable at the + // client -> use a standard throwable to represent the cause. + Throwable res = new Throwable(firstLine.substring(firstLine.indexOf(":") + 2)); + List<StackTraceElement> stackTraceList = new ArrayList<StackTraceElement>(); + while (st.hasMoreTokens()) { + String oneLine = st.nextToken(); + if (oneLine.startsWith("Caused by:")) { + Throwable nestedCause = getCause(st, oneLine); + res.initCause(nestedCause); + break; + } + stackTraceList.add(parseStackTrackLine(oneLine)); + } + StackTraceElement[] stackTraceElement = new StackTraceElement[stackTraceList.size()]; + res.setStackTrace(stackTraceList.toArray(stackTraceElement)); + return res; + } + + private static StackTraceElement parseStackTrackLine(String oneLine) { + StringTokenizer stInner = new StringTokenizer(oneLine, "!"); + return new StackTraceElement(stInner.nextToken(), stInner.nextToken(), + stInner.nextToken(), Integer.parseInt(stInner.nextToken())); + } private Class<?> getPrimitiveClass(Class<?> cls) { if (cls.isPrimitive()) {
