001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.node.protocol;
020
021import org.jppf.utils.ExceptionUtils;
022
023/**
024 * Instances of this class are used to signal that a task could not be sent back by the node to the server.
025 * <p>This generally happens when a task cannot be serialized after its execution, or if a data transformation is
026 * applied and fails with an exception. An instance of this class captures the context of the error, including the exception
027 * that occurred, the object's <code>toString()</code> descriptor and its class name.
028 * <p>When such an error occurs, an instance of this class will be sent instead of the initial JPPF task.
029 * @author Laurent Cohen
030 */
031public class JPPFExceptionResult extends AbstractTask<Object> {
032  /**
033   * Explicit serialVersionUID.
034   */
035  private static final long serialVersionUID = 1L;
036  /**
037   * This captures the result of ("" + object).
038   */
039  protected String objectDescriptor;
040  /**
041   * The fully qualified class name of the object that triggered the error.
042   */
043  protected String className;
044
045  /**
046   * Default constructor provided as a convenience for subclassing.
047   */
048  public JPPFExceptionResult() {
049  }
050
051  /**
052   * Initialize this task with the specified error context.
053   * @param throwable the throwable that is to be captured.
054   * @param object the object on which the throwable applies.
055   */
056  public JPPFExceptionResult(final Throwable throwable, final Object object) {
057    setThrowable(throwable);
058    if (object instanceof String) {
059      objectDescriptor = (String) object;
060      className = "unknown class";
061    } else {
062      objectDescriptor = String.valueOf(object);
063      className = (object != null) ? object.getClass().getName() : "unknown class";
064    }
065  }
066
067  /**
068   * Display the error context captured in this task.
069   * @see java.lang.Runnable#run()
070   */
071  @Override
072  public void run() {
073    //System.out.println(toString());
074  }
075
076  /**
077   * Construct a string representation of this object.
078   * @return a string representing this JPPFExceptionResult.
079   * @see java.lang.Object#toString()
080   */
081  @Override
082  public String toString() {
083    final StringBuilder sb = new StringBuilder();
084    sb.append("Error occurred on object [").append(objectDescriptor).append("], class=").append(className);
085    if (getThrowable() != null) sb.append(" :\n").append(ExceptionUtils.getStackTrace(getThrowable()));
086    return sb.toString();
087  }
088
089  /**
090   * Get a string describing the object on which the error occurred.
091   * @return "null" if the task was null, the result of its <code>toString()</code> method otherwise.
092   */
093  public String getObjectDescriptor() {
094    return objectDescriptor;
095  }
096
097  /**
098   * Get the fully qualified class name of the intiial task object on which the error occurred.
099   * @return "unknown class" if the task object was null, its class name otherwise.
100   */
101  public String getTaskClassName() {
102    return className;
103  }
104}