Grails XFire + Flex (flex xfire Error #2032: Streamfout.)

I’m building a small application for myself. It will manage my orders and invoices. Reason I’m doing this is mainly to try out new stuff. I thought I’ld try out a Grails soap backend with a Flex frontend. Doesn’t sound to difficult, right? Well I ran into a problem and it took me some time before I found a solution.

I had created a simple webservice that would return all my orders. Something like this piece of code

class PurchaseOrderWebService {

boolean transactional = true
static expose=[‘xfire’]

PurchaseOrder findById(Long id){
return PurchaseOrder.get(id)
}

PurchaseOrder[] findAll(){
println(‘listing all’)
return PurchaseOrder.list() as PurchaseOrder[]
}

PurchaseOrder save(PurchaseOrder order){
return order.save()
}
}

Pretty simple don’t ya think. This is now accessable as a soap webservice. In Flex I used the generator to generate all my stubs. The Flex code would look something like this

public function loadData():void
{
Alert.show(“test5”);
var service:generated.webservices.PurchaseOrderWeb = new generated.webservices.PurchaseOrderWeb();
service.addEventListener(FaultEvent.FAULT,errorHandler);
service.addfindAllEventListener(findAllListener);
service.findAll();
}

public function findAllListener(e:generated.webservices.FindAllResultEvent):void
{
this.orderDG.dataProvider = e.result;
}

Here I show the alert so I’m sure I’m not using a cached version of the SWF. However doing this returns a Error #2032. Why? Well I don’t know. I tried using the soap service from another programming language (c#) and it worked fine. After much googling I finally found the answer. For some reason Flex doesn’t like it when you don’t supply an argument to the soap call. The piece of code that finally did the trick looks like this

Grails

class PurchaseOrderWebService {

boolean transactional = true
static expose=[‘xfire’]

PurchaseOrder findById(Long id){
return PurchaseOrder.get(id)
}

PurchaseOrder[] findAll(String dummy){
println(‘listing all’)
return PurchaseOrder.list() as PurchaseOrder[]
}

PurchaseOrder save(PurchaseOrder order){
return order.save()
}

}

Flex

public function loadData():void
{
Alert.show(“test6”);
var service:generated.webservices.PurchaseOrderWeb = new generated.webservices.PurchaseOrderWeb();
service.addEventListener(FaultEvent.FAULT,errorHandler);
service.addfindAllEventListener(findAllListener);
service.findAll(“test”);
}

public function findAllListener(e:generated.webservices.FindAllResultEvent):void
{
this.orderDG.dataProvider = e.result;
}

Strange bug if you ask me. I hope this get’s indexed and it will help other people facing this problem.