messaging icon indicating copy to clipboard operation
messaging copied to clipboard

Clarify the difference (if any) between JMSException.getLinkedException() and JMSException.getCause()

Open glassfishrobot opened this issue 12 years ago • 7 comments

JMSException.getLinkedException() is usually containing the provider-specific Exception object, but there's also already the inherited Exception.getCause() method. JMS Providers could potentially return different things in each method, which would be confusing.

Also, 'exception un-nesting code' would typically use Exception.getCause() multiple times until getCause() returns null to get to the root cause which then usually contains a better error description. Since this 'exception un-nesting code' could catch exceptions from multiple API's it would be nice if JMS behaves just like any other library (let getCause() return the cause of the exception).

My proposal would be to require JMS providers to implement JMSException.getCause() like this:

@Override
    public Throwable getCause()
    {
        return getLinkedException();
    }

That way, JMS wouldn't play a special role when interpreting the cause of an exception.

Affected Versions

[2.0]

glassfishrobot avatar Jan 08 '13 13:01 glassfishrobot

  • Issue Imported From: https://github.com/javaee/jms-spec/issues/113
  • Original Issue Raised By:@glassfishrobot
  • Original Issue Assigned To: Unassigned

glassfishrobot avatar Feb 12 '18 18:02 glassfishrobot

@glassfishrobot Commented Reported by axel_podehl

glassfishrobot avatar Jan 08 '13 13:01 glassfishrobot

@glassfishrobot Commented @nigeldeakin said: Separately to this, the following comment was posted to [email protected]. I'm pasting it here so it can be considered as well. (Here's the direct link ):

I was wondering why JMSException does not support Java 1.4 exception chaining [1] (#getCause() vs. #getLinkedException()). It should be easy to retrofit (similar to InvocationTargetException) and reduce the confusion and potential for misuse. Also a constructor that takes a message string and a cause (like every other exception class) would be nice.

[1] http://docs.oracle.com/javase/1.4.2/docs/guide/lang/chained-exceptions.html

Cheers Philippe

glassfishrobot avatar Jan 11 '13 11:01 glassfishrobot

@glassfishrobot Commented @nigeldeakin said: These are both interesting and valid comments. However now JMS 2.0 has reached the public draft stage we need to avoid adding new features if at all possible and as this feature is unrelated to any of the changes in JMS 2.0 I think we should defer considering until JMS 2.1. This will allow time for both issues to be considered properly.

Tagging appropriately.

glassfishrobot avatar Jan 11 '13 11:01 glassfishrobot

@glassfishrobot Commented braghest said: The following is an attempt at a patch:

  • implements #getCause() to return the linked exception, this is consistent the the proposal of axel_podehl and how InvocationTargetException has been retrofitted in 1.4
  • pass a cause to the super constructor, this is taken from InvocationTargetException and prevents calls to #initCause
  • add two new constructors which additionally take a cause/linked exception
  • the serialVersionUID is already present and remains unchanged
Index: jms2.1/src/main/java/javax/jms/JMSException.java
===================================================================
--- jms2.1/src/main/java/javax/jms/JMSException.java	(revision 345)
+++ jms2.1/src/main/java/javax/jms/JMSException.java	(working copy)
@@ -49,12 +49,15 @@
  *        the standard exception message and is available via the
  *        {@code getMessage} method.
  *   <LI> A provider-specific string error code 
- *   <LI> A reference to another exception. Often a JMS API exception will 
- *        be the result of a lower-level problem. If appropriate, this 
- *        lower-level exception can be linked to the JMS API exception.
  * </UL>
  * 
- * @version JMS 2.0
+ * <P><p>As of release 2.1, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism. The "linked exception"
+ * that is accessed via the {@link #getLinkedException()} method is now known
+ * as the <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
+ * method, as well as the aforementioned "legacy method."
+ * 
+ * @version JMS 2.1
  * @since JMS 1.0
  * 
  **/
@@ -84,7 +87,7 @@
    **/
   public 
   JMSException(String reason, String errorCode) {
-    super(reason);
+    super(reason, null);  // Disallow initCause
     this.errorCode = errorCode;
     linkedException = null;
   }
@@ -96,10 +99,38 @@
    **/
   public 
   JMSException(String reason) {
-    super(reason);
+    super(reason, null);  // Disallow initCause
     this.errorCode = null;
     linkedException = null;
   }
+  
+  /** Constructs a {@code JMSException} with the specified reason 
+   *  error code and linked exception.
+   *
+   *  @param  reason        a description of the exception
+   *  @param  errorCode     a string specifying the vendor-specific
+   *        error code
+   *  @param  ex            the linked {@code Exception}
+   **/
+  public 
+  JMSException(String reason, String errorCode, Exception ex) {
+    super(reason, null);  // Disallow initCause +    this.errorCode = errorCode;
+    linkedException = ex;
+  }
+  
+  /** Constructs a {@code JMSException} with the specified reason and
+   * linked exception and with the error code defaulting to null.
+   *
+   *  @param  reason        a description of the exception
+   *  @param  ex            the linked {@code Exception}
+   **/
+  public 
+  JMSException(String reason, Exception ex) {
+    super(reason, null);  // Disallow initCause +    this.errorCode = null;
+    linkedException = ex;
+  }

   /** Gets the vendor-specific error code.
    *  @return   a string specifying the vendor-specific
@@ -112,6 +143,10 @@

   /**
    * Gets the exception linked to this one.
+   * 
+   * <p>This method predates the general-purpose exception chaining facility.
+   * The {@link Throwable#getCause()} method is now the preferred means of
+   * obtaining this information.
    *
    * @return the linked {@code Exception}, null if none
   **/
@@ -128,4 +163,16 @@
   public void setLinkedException(Exception ex) {
       linkedException = ex;
   } 
+
+  /**
+   * Returns the cause of this exception (the thrown target exception,
+   * which may be {@code null}).
+   *
+   * @return  the cause of this exception.
+   * @since   2.1
+   */
+  @Override
+  public Throwable getCause() {
+    return (linkedException);
+  }
 }

glassfishrobot avatar Nov 01 '15 15:11 glassfishrobot

@glassfishrobot Commented braghest said: I just found out that EjbException#getCausedByException() was retrofitted in much the same way.

glassfishrobot avatar Feb 12 '16 14:02 glassfishrobot

@glassfishrobot Commented This issue was imported from java.net JIRA JMS_SPEC-113

glassfishrobot avatar May 02 '17 10:05 glassfishrobot