You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by st...@apache.org on 2009/05/27 12:59:29 UTC
svn commit: r779105 -
/hadoop/core/branches/HADOOP-3628-2/src/core/org/apache/hadoop/io/ThrowableWritable.java
Author: stevel
Date: Wed May 27 10:59:29 2009
New Revision: 779105
URL: http://svn.apache.org/viewvc?rev=779105&view=rev
Log:
HADOOP-3628 creating updated branch
Added:
hadoop/core/branches/HADOOP-3628-2/src/core/org/apache/hadoop/io/ThrowableWritable.java
Added: hadoop/core/branches/HADOOP-3628-2/src/core/org/apache/hadoop/io/ThrowableWritable.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/HADOOP-3628-2/src/core/org/apache/hadoop/io/ThrowableWritable.java?rev=779105&view=auto
==============================================================================
--- hadoop/core/branches/HADOOP-3628-2/src/core/org/apache/hadoop/io/ThrowableWritable.java (added)
+++ hadoop/core/branches/HADOOP-3628-2/src/core/org/apache/hadoop/io/ThrowableWritable.java Wed May 27 10:59:29 2009
@@ -0,0 +1,278 @@
+/**
+ * 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.hadoop.io;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/** This writable component builds from a throwable */
+
+public final class ThrowableWritable implements Writable {
+
+ /** throwable classname */
+ private String classname;
+
+ /** throwable message */
+
+ private String message;
+ /** cause: may be null */
+ private ThrowableWritable cause;
+
+ /**
+ * Stack trace as string; will be null when an empty element is created,
+ * otherwise it will be an array of length zero.
+ */
+ private String[] stack;
+
+
+ /**
+ * Empty constructor.
+ * Only use this when you are planning to deserialize data, as the object is
+ * otherwise incomplete.
+ */
+ public ThrowableWritable() {
+ }
+
+
+ /**
+ * Construct a lightweight throwable writeable with no stack trace; and the
+ * message passed in
+ *
+ * @param message message to use
+ */
+ public ThrowableWritable(String message) {
+ this.message = message;
+ stack = new String[0];
+ classname = "";
+ }
+
+ /**
+ * recursively construct from a throwable chain.
+ *
+ * @param thrown The throwable chain to build this writeable from.
+ */
+ public ThrowableWritable(Throwable thrown) {
+ classname = thrown.getClass().getName();
+ message = thrown.getMessage();
+
+ StackTraceElement[] st = thrown.getStackTrace();
+ if (st != null) {
+ int sl = st.length;
+ stack = new String[sl];
+ for (int i = 0; i < sl; i++) {
+ stack[i] = st[i].toString();
+ }
+ } else {
+ stack = new String[0];
+ }
+ Throwable rootCause = thrown.getCause();
+ if (rootCause != null && rootCause != thrown) {
+ cause = new ThrowableWritable(rootCause);
+ }
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param that the original instance to copy
+ */
+ public ThrowableWritable(ThrowableWritable that) {
+ classname = that.classname;
+ message = that.message;
+ //copy stack trace
+ if (that.stack == null) {
+ stack = new String[0];
+ } else {
+ int l = that.stack.length;
+ stack = new String[l];
+ System.arraycopy(that.stack, 0, stack, 0, l);
+ }
+ //copy any nested cause
+ if (that.cause != null) {
+ cause = new ThrowableWritable(that.cause);
+ }
+ }
+
+
+ /**
+ * Get the classname of the underlying throwable
+ *
+ * @return the classname of the original throwable
+ */
+ public String getClassname() {
+ return classname;
+ }
+
+ /**
+ * Get the text string this instance was constructed with
+ *
+ * @return the message of the underlying throwable
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Get any nested cause of the exception
+ *
+ * @return any nested cause as another ThrowableWritable -or null
+ */
+ public ThrowableWritable getCause() {
+ return cause;
+ }
+
+ /**
+ * Get the stack trace of the original throwable. It may be of size 0.
+ *
+ * @return the stack trace converted to strings
+ */
+ public String[] getStack() {
+ return stack;
+ }
+
+
+ /**
+ * determine (recursively) the depth of this Throwable chain
+ *
+ * @return a number equal to or greater than 1
+ */
+ public int getDepth() {
+ return 1 + (cause == null ? 0 : cause.getDepth());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param out <code>DataOutput</code> to serialize this object into.
+ *
+ * @throws IOException IO trouble
+ */
+ public void write(DataOutput out) throws IOException {
+ out.writeUTF(classname);
+ out.writeUTF(message);
+ if (stack != null) {
+ out.writeInt(stack.length);
+ for (String call : stack) {
+ out.writeUTF(call);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ //look for a cause
+ boolean hasCause = cause != null;
+ out.writeBoolean(hasCause);
+ if (hasCause) {
+ //recursively write it
+ cause.write(out);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param in <code>DataInput</code> to deseriablize this object from.
+ *
+ * @throws IOException IO trouble
+ */
+ public void readFields(DataInput in) throws IOException {
+ classname = in.readUTF();
+ message = in.readUTF();
+ int stackLength = in.readInt();
+ if (stack == null || stack.length != stackLength) {
+ //create a new stack array
+ stack = new String[stackLength];
+ }
+ //read in the stack
+ for (int i = 0; i < stackLength; i++) {
+ stack[i] = in.readUTF();
+ }
+ //look for any nested cause
+ boolean hasCause = in.readBoolean();
+ if (hasCause) {
+ if (cause == null) {
+ cause = new ThrowableWritable();
+ }
+ cause.readFields(in);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws CloneNotSupportedException this should not happen
+ */
+ @SuppressWarnings({"CloneDoesntCallSuperClone"})
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ return new ThrowableWritable(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The classname and message are used for equality
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ThrowableWritable that = (ThrowableWritable) o;
+
+ if (classname != null ? !classname.equals(that.classname) : that.classname != null)
+ return false;
+ return !(message != null ? !message.equals(that.message) : that.message != null);
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The classname and message are used in the hash
+ */
+ @Override
+ public int hashCode() {
+ int result = classname != null ? classname.hashCode() : 0;
+ result = 31 * result + (message != null ? message.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Return the classname and message in the format classname: message The
+ * output is designed to resemble that of {@link Throwable#toString()} if the
+ * message and classname are both set. If only the message is set, only that
+ * is printed.
+ *
+ * @return a string representation of the object.
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ if (classname != null) {
+ builder.append(classname);
+ if (!classname.isEmpty()) {
+ builder.append(": ");
+ }
+ }
+ if (message != null) {
+ builder.append(message);
+ }
+ return builder.toString();
+ }
+}