Java – How to handle custom Java exception in Flex app

apache-flexblazedsjava

we are using BlazeDS as a proxy between Flex and Java. The approach is the same as in (http://www.flexpasta.com/index.php/2008/05/16/exception-handling-with-blazeds-and-flex/)

Java exception declaration:

public class FlexException extends RuntimeException {
 private String name = 'John';

 public FlexException(String message) {
   super(message);
 }

 public String getName() {
   return name;
 }
}

Then, we are throwing it:

public void testMethod(String str) throws Exception {
 throw new FlexException("Custom exception");
}

Flex part:

private function faultHandler(event:FaultEvent):void
{
  var errorMessage:ErrorMessage = event.message as ErrorMessage;
  trace("error++");
}

and remote object is instantiated here:

<mx:RemoteObject id="mySample" destination="mySample" channelSet="{cs1}" fault="faultHandler(event)" />

But in event.fault I get "Server.Processing" and event.faultString equals "There was an unhandled failure on the server. Custom exception"
How can I receive the data is specified in exception props ?

UPDATE:
Configuration files:
messaging-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<adapters>
    <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
    <!-- <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> -->
</adapters>

<default-channels>
    <channel ref="my-polling-amf"/>
</default-channels>

proxy-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<service id="proxy-service" 
    class="flex.messaging.services.HTTPProxyService">

    <properties>
        <connection-manager>
            <max-total-connections>100</max-total-connections>
            <default-max-connections-per-host>2</default-max-connections-per-host>
        </connection-manager>
        <allow-lax-ssl>true</allow-lax-ssl>
    </properties>

    <adapters>
        <adapter-definition id="http-proxy" class="flex.messaging.services.http.HTTPProxyAdapter" default="true"/>
        <adapter-definition id="soap-proxy" class="flex.messaging.services.http.SOAPProxyAdapter"/>
    </adapters>

    <default-channels>
        <channel ref="my-amf"/>
    </default-channels>

    <destination id="DefaultHTTP">
    </destination>

</service>

remoting-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<adapters>
    <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
</adapters>

<default-channels>
    <channel ref="my-amf"/>
</default-channels>

services-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<services>
    <service-include file-path="remoting-config.xml" />
    <service-include file-path="proxy-config.xml" />
    <service-include file-path="messaging-config.xml" />        
</services>

<security>
    <login-command class="flex.messaging.security.TomcatLoginCommand" server="Tomcat"/>
    <!-- Uncomment the correct app server
    <login-command class="flex.messaging.security.TomcatLoginCommand" server="JBoss">
    <login-command class="flex.messaging.security.JRunLoginCommand" server="JRun"/>        
    <login-command class="flex.messaging.security.WeblogicLoginCommand" server="Weblogic"/>
    <login-command class="flex.messaging.security.WebSphereLoginCommand" server="WebSphere"/>
    -->

    <!-- 
    <security-constraint id="basic-read-access">
        <auth-method>Basic</auth-method>
        <roles>
            <role>guests</role>
            <role>accountants</role>
            <role>employees</role>
            <role>managers</role>
        </roles>
    </security-constraint>
     -->
</security>

<channels>

    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
        <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
    </channel-definition>

    <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
        <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
        <properties>
            <add-no-cache-headers>false</add-no-cache-headers>
        </properties>
    </channel-definition>

    <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
        <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
        <properties>
            <polling-enabled>true</polling-enabled>
            <polling-interval-seconds>4</polling-interval-seconds>
        </properties>
    </channel-definition>

    <!--
    <channel-definition id="my-http" class="mx.messaging.channels.HTTPChannel">
        <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/http" class="flex.messaging.endpoints.HTTPEndpoint"/>
    </channel-definition>

    <channel-definition id="my-secure-http" class="mx.messaging.channels.SecureHTTPChannel">
        <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/httpsecure" class="flex.messaging.endpoints.SecureHTTPEndpoint"/>
        <properties>
            <add-no-cache-headers>false</add-no-cache-headers>
        </properties>
    </channel-definition>
    -->
</channels>

<logging>
    <target class="flex.messaging.log.ConsoleTarget" level="Debug">
        <properties>
            <prefix>[BlazeDS] </prefix>
            <includeDate>true</includeDate>
            <includeTime>true</includeTime>
            <includeLevel>true</includeLevel>
            <includeCategory>true</includeCategory>
        </properties>
        <filters>
            <pattern>Endpoint.*</pattern>
            <pattern>Service.*</pattern>
            <pattern>Configuration</pattern>
        </filters>
    </target>
</logging>

<system>
    <redeploy>
        <enabled>false</enabled>
        <!-- 
        <watch-interval>20</watch-interval>
        <watch-file>{context.root}/WEB-INF/flex/services-config.xml</watch-file>
        <watch-file>{context.root}/WEB-INF/flex/proxy-config.xml</watch-file>
        <watch-file>{context.root}/WEB-INF/flex/remoting-config.xml</watch-file>
        <watch-file>{context.root}/WEB-INF/flex/messaging-config.xml</watch-file>
        <watch-file>{context.root}/WEB-INF/flex/data-management-config.xml</watch-file>
        <touch-file>{context.root}/WEB-INF/web.xml</touch-file>
         -->
    </redeploy>
</system>

Spring config:

<bean id="mySample" class="ru.crystals.pos.testFlexConnection.Test">
    <constructor-arg ref="defaultMessageTemplate" />
    <flex:remoting-destination />
</bean>

This is a log from Tomcat

    [BlazeDS]03/23/2010 14:46:51.870 [DEBUG] [Endpoint.AMF] Serializing AMF/HTTP res
ponse
Version: 3
  (Message #0 targetURI=/1/onStatus, responseUR|-)
    (Typed Object #0 'flex.messaging.messages.ErrorMessage')
      headers = (Object #1)
      rootCause = null
      body = null
      correlationId = "2EB1C972-B32B-03BA-825C-8AD8B9DFCEF8"
      faultDetail = null
      faultString = "There was an unhandled failure on the server. Custom except
ion"
      clientId = "89FB2149-6E0F-4FB6-4D5E-EC838139EE90"
      timeToLive = 0.0
      destination = "mySample"
      timestamp = 1.269344811854E12
      extendedData = null
      faultCode = "Server.Processing"
      messageId = "89FB2149-6E1A-4453-6E45-55A93BBA50AF"

Here is what I get in Flex when setting a breakpoint in the onFaultHandler:
alt text

So the quesion is why rootClause is null? Where is my FlexException with name = 'John'.

Best Answer

Ok, so you are using the spring-blazeds-flex integration. In this case the mechanism described on the previous links does not work as it is. You need to create your own exception translator, otherwise you will receive the generic Server.Processing error: . Please read: http://static.springsource.org/spring-flex/docs/1.0.x/reference/html/ch02s08.html

Also you can read on the blog of my friend Ionut this article: http://margelatu.org/2009/06/15/meaningful-exceptions-in-lcdsblazeds-applications-using-spring-blazeds-integration/