1 Reply Latest reply on Mar 26, 2013 6:24 PM by Christian Sadilek

    Solution for "class is not available to the marshaller framework: ...Exception"

    Thomas Frühbeck Newbie

      Hi,

       

      since the advent of modern programming styles it becomes more frequent that Exceptions are not part of the interface's method signatures.

      Even more since EJB3 with CMT beans and interceptors nearly _any_ exception may occur. Unfortunately the current implementation of Errai Marshalling forces to

           - declare _every_ Exception also for Client side to have consistent exception handling (e.g. TxTimeout, SecurityException, RemoteException...)

           - the standard marshalling will take the complete Exception stack and send it to the client (incl Stacktrace!!)

           - if not the client will starve, not knowing anything about the outcome of its call

       

      This may be desirable for very curious clients, and in such cases developers will provide the means for it.

      In my case I just want a reliable and consistent Exception propagation, not so much in need of the absolute details of stack trace etc.

      So I propose the following pragmatic but simple change:

       

      MappingContextSingleton:

       

          final MappingDefinition def = factory.getDefinition(clazz);

       

         

      if (def == null) {

           if (clazz.toLowerCase().endsWith("exception")) {   // sorry, is a bit silly but works in a _lot_ of cases

                return new FallbackExceptionMarshaller();

           }

            throw new MarshallingException("class is not available to the marshaller framework: " + clazz);
          }

       

      The FallbackExceptionMarshaller simply could map the unknown exception to RuntimeException:

       

          public String doNotNullMarshall(Object o, MarshallingSession ctx) {        

                return "{\"" + SerializationParts.ENCODED_TYPE + "\":\"" + RuntimeException.class.getName() + "\","

                       + "\"" + SerializationParts.OBJECT_ID + "\":\"" + o.hashCode() + "\","

                       + "\"" + "message" + "\":\"" + MarshallUtil.jsonStringEscape(getCause(((Exception)o)).getMessage()) + "\"}";

           }

       

           Throwable getCause(Throwable e) {

               if (e.getCause() != null) {            

                return getCause(e.getCause());

               }

               return e;

           }

       

      We have implemented and tested this in 2.2.0 and are quite happy with this solution.

      WDYT?