You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@axis.apache.org by ba...@apache.org on 2011/02/27 15:11:00 UTC
svn commit: r1075057 - in /axis/axis2/java/core/trunk/modules/jaxws:
src/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
test/org/apache/axis2/jaxws/WebServiceExceptionLoggerTests.java
Author: barrettj
Date: Sun Feb 27 14:11:00 2011
New Revision: 1075057
URL: http://svn.apache.org/viewvc?rev=1075057&view=rev
Log:
Prevent index out of bounds exception, or any exception, from attempting to log. Add TDD/UT for same.
Added:
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/WebServiceExceptionLoggerTests.java
Modified:
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/WebServiceExceptionLogger.java?rev=1075057&r1=1075056&r2=1075057&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/WebServiceExceptionLogger.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/WebServiceExceptionLogger.java Sun Feb 27 14:11:00 2011
@@ -52,68 +52,80 @@ public class WebServiceExceptionLogger {
Class serviceImplClass,
Object serviceInstance,
Object[] args) {
-
- // Must have debug or error logging enabled
- if (!log.isDebugEnabled() && !log.isErrorEnabled()) {
- return;
- }
-
- // Get the root of the exception
- Throwable rootT = null;
- if (throwable instanceof InvocationTargetException) {
- rootT = ((InvocationTargetException) throwable).getTargetException();
- }
-
-
- String name = rootT.getClass().getName();
- String stack = stackToString(rootT);
-
- // Determine if this is a checked exception or non-checked exception
- Class checkedException = JavaUtils.getCheckedException(rootT, method);
-
- if (checkedException == null) {
- // Only log errors for non-checked exceptions
- if (log.isErrorEnabled()) {
- String text = "";
- if (logFully) {
- text = Messages.getMessage("failureLogger", name, rootT.toString());
-
- } else {
- text = Messages.getMessage("failureLogger", name, stack);
- }
- log.error(text);
+
+ // No matter what happens in this logging method, do not surface that exception. We don't want a logging
+ // failure to mask the real exception we are trying to log or affect subsequent processing.
+ try {
+
+ // Must have debug or error logging enabled
+ if (!log.isDebugEnabled() && !log.isErrorEnabled()) {
+ return;
}
- }
-
- // Full logging if debug is enabled.
- if (log.isDebugEnabled()) {
- log.debug("Exception invoking a method of " + serviceImplClass.toString()
- + " of instance " + serviceInstance.toString());
- log.debug("Exception type thrown: " + throwable.getClass().getName());
- if (rootT != null) {
- log.debug("Root Exception type thrown: " + rootT.getClass().getName());
- }
- if (checkedException != null) {
- log.debug("The exception is an instance of checked exception: " +
- checkedException.getName());
+ // Get the root of the exception
+ Throwable rootT = null;
+ if (throwable instanceof InvocationTargetException) {
+ rootT = ((InvocationTargetException) throwable).getTargetException();
+ } else {
+ rootT = throwable;
}
- // Extra trace if ElementNSImpl incompatibility problem.
- // The incompatibility exception occurs if the JAXB Unmarshaller
- // unmarshals to a dom element instead of a generated object. This can
- // result in class cast exceptions. The solution is usually a missing
- // @XmlSeeAlso annotation in the jaxws or jaxb classes.
- if (rootT.toString().contains("org.apache.xerces.dom.ElementNSImpl incompatible")) {
- log.debug("This exception may be due to a missing @XmlSeeAlso in the client's jaxws or" +
- " jaxb classes.");
+ String name = rootT.getClass().getName();
+ log.debug("693210: root Throwable, may cause index error: " + rootT.toString(), rootT);
+ String stack = stackToString(rootT);
+
+ // Determine if this is a checked exception or non-checked exception
+ Class checkedException = JavaUtils.getCheckedException(rootT, method);
+
+ if (checkedException == null) {
+ // Only log errors for non-checked exceptions
+ if (log.isErrorEnabled()) {
+ String text = "";
+ if (logFully) {
+ text = Messages.getMessage("failureLogger", name, rootT.toString());
+
+ } else {
+ text = Messages.getMessage("failureLogger", name, stack);
+ }
+ log.error(text);
+ }
+
+ }
+
+ // Full logging if debug is enabled.
+ if (log.isDebugEnabled()) {
+ log.debug("Exception invoking a method of " + serviceImplClass.toString()
+ + " of instance " + serviceInstance.toString());
+ log.debug("Exception type thrown: " + throwable.getClass().getName());
+ if (rootT != null) {
+ log.debug("Root Exception type thrown: " + rootT.getClass().getName());
+ }
+ if (checkedException != null) {
+ log.debug("The exception is an instance of checked exception: " +
+ checkedException.getName());
+ }
+
+ // Extra trace if ElementNSImpl incompatibility problem.
+ // The incompatibility exception occurs if the JAXB Unmarshaller
+ // unmarshals to a dom element instead of a generated object. This can
+ // result in class cast exceptions. The solution is usually a missing
+ // @XmlSeeAlso annotation in the jaxws or jaxb classes.
+ if (rootT.toString().contains("org.apache.xerces.dom.ElementNSImpl incompatible")) {
+ log.debug("This exception may be due to a missing @XmlSeeAlso in the client's jaxws or" +
+ " jaxb classes.");
+ }
+ log.debug("Method = " + method.toGenericString());
+ for (int i = 0; i < args.length; i++) {
+ String value =
+ (args[i] == null) ? "null"
+ : args[i].getClass().toString();
+ log.debug(" Argument[" + i + "] is " + value);
+ }
}
- log.debug("Method = " + method.toGenericString());
- for (int i = 0; i < args.length; i++) {
- String value =
- (args[i] == null) ? "null"
- : args[i].getClass().toString();
- log.debug(" Argument[" + i + "] is " + value);
+ } catch (Throwable t) {
+ if (log.isDebugEnabled()) {
+ log.debug("Caught throwable in logger", t);
+ log.debug("While attempting to log original exception", throwable);
}
}
return;
@@ -126,15 +138,18 @@ public class WebServiceExceptionLogger {
* @param e
* @return
*/
- private static String stackToString(Throwable e) {
+ static String stackToString(Throwable e) {
java.io.StringWriter sw = new java.io.StringWriter();
java.io.BufferedWriter bw = new java.io.BufferedWriter(sw);
java.io.PrintWriter pw = new java.io.PrintWriter(bw);
e.printStackTrace(pw);
pw.close();
String text = sw.getBuffer().toString();
- // Jump past the throwable
- text = text.substring(text.indexOf("at"));
+ // Jump past the name of the throwable cause in the stack
+ int indexOfThrowable = text.indexOf("at");
+ if (indexOfThrowable > 0) {
+ text = text.substring(indexOfThrowable);
+ }
return text;
}
Added: axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/WebServiceExceptionLoggerTests.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/WebServiceExceptionLoggerTests.java?rev=1075057&view=auto
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/WebServiceExceptionLoggerTests.java (added)
+++ axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/WebServiceExceptionLoggerTests.java Sun Feb 27 14:11:00 2011
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+/**
+ * Validate the WebServiceExeptionLogger
+ */
+public class WebServiceExceptionLoggerTests extends TestCase {
+
+ /**
+ * Validate that if we pass in an exception without any stack information, it does not cause an exception.
+ */
+ public void testNoStack() {
+
+ ServiceClass serviceClass = new ServiceClass();
+ Method method = null;
+ try {
+ method = ImplClass.class.getDeclaredMethod("implMethod");
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Test implementation error: unable to get test class method due to exception: " + e.toString());
+ }
+ Exception rootCause = new EmptyStackTraceException();
+ InvocationTargetException invTargetExc = new InvocationTargetException(rootCause);
+ WebServiceExceptionLogger.log(method,
+ invTargetExc,
+ false,
+ ImplClass.class,
+ serviceClass,
+ null);
+ }
+
+ /**
+ * Validate that a exception that is not of type InvocationTargetException does not cause any issues in the logger.
+ */
+ public void testNonInvocationTargetException() {
+
+ ServiceClass serviceClass = new ServiceClass();
+ Method method = null;
+ try {
+ method = ImplClass.class.getDeclaredMethod("implMethod");
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Test implementation error: unable to get test class method due to exception: " + e.toString());
+ }
+ Exception rootCause = new NonemptyStackTraceException();
+ WebServiceExceptionLogger.log(method,
+ rootCause,
+ false,
+ ImplClass.class,
+ serviceClass,
+ null);
+ }
+
+ /**
+ * Validate the stackToString method works if there is no stack returned by the exception passed in. It is necessary
+ * to validate this method directly since the WebServcieExceptionLogger.log method will catch all exceptions so it
+ * will never fail.
+ */
+ public void testStackToStrig_NoStack() {
+ String returnedStack = WebServiceExceptionLogger.stackToString(new EmptyStackTraceException());
+ // If we don't get an exception, then this test passes.
+ }
+
+ /**
+ * Validate that the returned stack skips over the original throwable's name.
+ */
+ public void testStackToString() {
+ Exception nonEmpty = new NonemptyStackTraceException();
+ String returnedStack = WebServiceExceptionLogger.stackToString(nonEmpty);
+ assertFalse("Returned stack did not skip the original throwable", returnedStack.contains("NonemptyStackTraceException"));
+ }
+
+ class ImplClass {
+
+ public String implMethod() { return "foo"; }
+
+ }
+
+ class ServiceClass {
+
+ }
+
+ class EmptyStackTraceException extends Exception {
+ public void printStackTrace(PrintWriter err) { }
+ }
+
+ class NonemptyStackTraceException extends Exception {
+ }
+}