4 Replies Latest reply on Dec 27, 2012 3:24 PM by kcbabo

    SwitchYard RemoteInvoker Exception Handling

    yusufb

      I've used the RemoteInvoker to link to a SwitchYard service successfully. The service interface declares that it throws an Exception and its implemented on the corresponding ServiceBean. However, when an Exception is thrown from the service on the server, the following error occurs on the client when using the RemoteInvoker to invoke the service:

       

      java.lang.RuntimeException: java.lang.NoSuchMethodException: java.lang.StackTraceElement.<init>()
                at org.switchyard.common.type.reflect.Construction.construct(Construction.java:166)
                at org.switchyard.common.type.reflect.Construction.construct(Construction.java:71)
                at org.switchyard.serial.graph.DefaultFactory.create(DefaultFactory.java:37)
                at org.switchyard.serial.graph.node.AccessNode.decompose(AccessNode.java:133)
                at org.switchyard.serial.graph.Graph.decomposeReference(Graph.java:150)
                at org.switchyard.serial.graph.node.ArrayNode.decompose(ArrayNode.java:73)
                at org.switchyard.serial.graph.Graph.decomposeReference(Graph.java:150)
                at org.switchyard.serial.graph.node.AccessNode$1.run(AccessNode.java:145)
                at org.switchyard.serial.graph.Graph.decomposeRoot(Graph.java:136)
                at org.switchyard.serial.graph.GraphSerializer.deserialize(GraphSerializer.java:66)
                at org.switchyard.remote.http.HttpInvoker.invoke(HttpInvoker.java:130)
                at za.co.fnb.soa.registry.tests.remote.MyRemoteTests.myRemoteTest1(MyRemoteTests.java:54)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:597)
                at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
                at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
                at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
                at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
                at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
                at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
                at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
                at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
                at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
                at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
                at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
                at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
                at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
                at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
                at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
      Caused by: java.lang.NoSuchMethodException: java.lang.StackTraceElement.<init>()
                at java.lang.Class.getConstructor0(Class.java:2706)
                at java.lang.Class.getDeclaredConstructor(Class.java:1985)
                at org.switchyard.common.type.reflect.Construction.construct(Construction.java:161)
                ... 34 more
      

       

      It looks like the StackTraceElement doesn't have a default constructor, which seems to be required for deserialization. It's critical that Error information make it across to the client.  Is there a workaround to get this working? Any other ideas?

       

      Thanks,

      Yusuf.

        • 1. Re: SwitchYard RemoteInvoker Exception Handling
          dward

          Yusuf, just wanted to let you know that a handful of us have been digging into exception handling today, and I'll look a bit more at this and ramifications on serialization tomorrow. Thanks for your patience; we've been a bit "heads down" with 0.7.

          • 2. Re: SwitchYard RemoteInvoker Exception Handling
            dward

            Yusuf, changes have/are being made for the upcoming 0.7 release which turns Throwable StackTraceElements (and also DOM Nodes) into Strings before they get sent over the wire, so hopefully this issue should go away for you in 0.7.  We might change how this is done for 0.8, however.  I will let Keith provide better detail for you when he gets the chance.  Thanks for your patience!

            1 of 1 people found this helpful
            • 3. Re: SwitchYard RemoteInvoker Exception Handling
              yusufb

              Awesome, thanks for the feedback David. I also considered adding a handler on the server side to wrap the exception in a serialised form, then unwrap it on the client side. Sounds good.

               

              Is there a release schedule I can have a look at somewhere? Any idea when the 0.7  Release will be made? What about the 0.8 Release?

               

              Thanks,

              Yusuf.

              • 4. Re: SwitchYard RemoteInvoker Exception Handling
                kcbabo

                We are very close to cutting the 0.7 release, so this will need to be fixed in phases.  For 0.7, I have introduced a workaround inside the remote binding to convert exceptions to string payloads:

                https://issues.jboss.org/browse/SWITCHYARD-1228

                 

                Your fault handling code would look something like this:

                        RemoteMessage msg = invoker.invoke(new RemoteMessage()
                            .setService(new QName("urn:com.example.switchyard:cluster1:0.0.1-SNAPSHOT", "Dealer"))
                            .setContent(offer));
                
                        if (msg.isFault()) {
                            System.out.println(msg.getContent());
                        } else {
                            Deal deal = (Deal) msg.getContent();
                            System.out.println("It's a deal? " + deal.isAccepted());
                        }
                

                 

                As David mentioned, we will revisit this in 0.8 and look to reconstitute the exception instead of converting to string.

                 

                In terms of release schedule, I expect 0.7 to be released the second week of January.  A 0.8 release will follow approx. 6-8 weeks after that.