001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.remoting.support; 018 019import java.util.HashSet; 020import java.util.Set; 021 022/** 023 * General utilities for handling remote invocations. 024 * 025 * <p>Mainly intended for use within the remoting framework. 026 * 027 * @author Juergen Hoeller 028 * @since 2.0 029 */ 030public abstract class RemoteInvocationUtils { 031 032 /** 033 * Fill the current client-side stack trace into the given exception. 034 * <p>The given exception is typically thrown on the server and serialized 035 * as-is, with the client wanting it to contain the client-side portion 036 * of the stack trace as well. What we can do here is to update the 037 * {@code StackTraceElement} array with the current client-side stack 038 * trace, provided that we run on JDK 1.4+. 039 * @param ex the exception to update 040 * @see Throwable#getStackTrace() 041 * @see Throwable#setStackTrace(StackTraceElement[]) 042 */ 043 public static void fillInClientStackTraceIfPossible(Throwable ex) { 044 if (ex != null) { 045 StackTraceElement[] clientStack = new Throwable().getStackTrace(); 046 Set<Throwable> visitedExceptions = new HashSet<Throwable>(); 047 Throwable exToUpdate = ex; 048 while (exToUpdate != null && !visitedExceptions.contains(exToUpdate)) { 049 StackTraceElement[] serverStack = exToUpdate.getStackTrace(); 050 StackTraceElement[] combinedStack = new StackTraceElement[serverStack.length + clientStack.length]; 051 System.arraycopy(serverStack, 0, combinedStack, 0, serverStack.length); 052 System.arraycopy(clientStack, 0, combinedStack, serverStack.length, clientStack.length); 053 exToUpdate.setStackTrace(combinedStack); 054 visitedExceptions.add(exToUpdate); 055 exToUpdate = exToUpdate.getCause(); 056 } 057 } 058 } 059 060}