Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ColdFusion not catching NoClassDefFoundError

I am using ColdFusion 8. I would like to catch a NoClassDefFoundError exception in ColdFusion however I can't... It still fails and logs the error in the exception.log file. Here is what I tried.

<cftry>
    <cfset myJavaObject.myMethod()>
    <cfcatch type="any">
        <cfdump var="#cfcatch #">
    </cfcatch>
    <cfcatch type="java.lang.Throwable">
        Horrible exception.
        <cfdump var="#cfcatch #">
    </cfcatch>
</cftry>

But this does not work. Could you please show me how to do that? I need to catch this error at a particular place and not in the OnError function of my Application.cfc.

like image 757
Abbadon Avatar asked Jan 09 '13 14:01

Abbadon


1 Answers

Now that I have had more coffee, I do not think cfcatch is capable of catching a NoClassDefFoundError. According to the documentation, it only processes Exceptions:

Exceptions are events that disrupt the normal flow of instructions in a ColdFusion page, such as failed database operations, missing include files, and developer-specified events.

NoClassDefFoundError is an Error.

An Error indicates serious problems that a reasonable application should not try to catch

It sounds like cfcatch was only designed to handle normal "recoverable" problems. There is really not much you can do once you get a NoClassDefFoundError. It is a severe error and you cannot get past it (under normal circumstances). The most you can do is show an error message and exit.

Application.onError seems to handle uncaught Errors like NoClassDefFoundError, as well as Exceptions. So I think the best you can do is implement onError and have it display an error page.

    <!---- test code --->
    <cfset myJavaObject = createObject("java", "path.to.MyClass") />
    <cfset myJavaObject.myMethod() />

    <!---- Application.cfc --->
    <cfcomponent>
         .... settings ...
         <cffunction name="onError" returnType="void"> 
             <cfargument name="Exception" required="true" /> 
             <cfargument name="EventName" type="string" required="true" /> 
             <h1>onError Test</h1>
             <cfdump var="#Exception#" />
         </cffunction>
    </cfcomponent>

    // test class
    public class MyClass {
        public void myMethod() {
            throw new NoClassDefFoundError ("Testing...");
        }
    }

Update

The Any type includes all error with the Java object type of java.lang.Exception. It does not include java.lang.Throwable errors. To catch Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute

Despite what the documentation says, catching Throwable does not work in any of my tests (or yours). That strongly suggests a bug in the behavior or the documentation. Either way it does not work as advertised, so as mentioned above, the only alternative I know of is using a general error handler. If you must stick with an Application.cfm file for some reason, try using <cferror type="exception" ...>

(Absurd) Test case:

<cftry>
   <cfset myJavaObject = createObject("java", "path.to.MyClass")>
   <cfset myJavaObject.myMethod()>
   <cfcatch type="java.lang.NoClassDefFoundError">
      CAUGHT java.lang.NoClassDefFoundError
   </cfcatch>
   <cfcatch type="java.lang.LinkageError">
      CAUGHT java.lang.LinkageError
   </cfcatch>
   <cfcatch type="java.lang.Error">
      CAUGHT java.lang.Error
   </cfcatch>
   <cfcatch type="java.lang.Throwable">
      CAUGHT java.lang.Throwable 
   </cfcatch>
   <cfcatch type="any">
      CAUGHT ANY
   </cfcatch>
   <cfcatch>
      CAUGHT
   </cfcatch>
</cftry>
like image 160
Leigh Avatar answered Nov 02 '22 02:11

Leigh