I was looking for a remoting implementation for a client related project, the entire back end in JAVA SOA, mainly session beans with proxies to web services. Using flash to talk to web services works but its a bit cumbersome and if you get into HTTPS calls its real pain.
I looked at openAMF and found the documentation virtually non existent, so had a look at flashORB and although it appeared more documented it was still a bit weak. What I wanted to know is how do I get flash to talk to an EJB.
I decided to get back to openAMF and started looking through the example code, various posts on their user list archives and finally cobbled together a test. Amazingly once you know how it should work, it works amazingly well. The biggest hurdles were understanding the difference between the standard gateway and the advanced gateway, understanding the AS1 code examples (I've had Actionscript 1.0 erased from my mind) and finally how to configure the openamf-config.xml file.
The way openAMF is setup you have a gateway where all open amf traffic will go, looking through the docs the default gateway will try and find a match for you service request so for example :
myService = new Service ( gatewayURL, null, "org.openamf.examples.Test3", null, null );
openAMF will try and find a service/object matching org.openamf.examples.Test3
This works but of course is a bit inefficient so the advanced gateway allows you to declare a service with a friendly name and then associate that with an object, jndi name, web service etc.
My test service is an administration session bean deployed to weblogic. Its JNDI name is
ejb/com.nscorp.identityServices.administrationService.interfaces.AdministrationServiceHome
so in the openamf-config.xml I enable the EJB invoker:
<invoker>
<name>EJB</name>
<class>org.openamf.invoker.EJBServiceInvoker</class>
</invoker>
Then within the Service tag (used by the advanced gateway) I include
<service>
<name>AdministrationService</name>
<invoker-ref>EJB</invoker-ref>
<service-location>ejb/com.nscorp.identityServices.administrationService.interfaces.AdministrationServiceHome</service-location>
<method>
<name>*</name>
<parameter>
<type>*</type>
</parameter>
</method>
</service>
This means I have a service called AdministrationService, openAMF should use the EJB invoker and the JNDI name is : ejb/com.nscorp.identityServices.administrationService.interfaces.AdministrationServiceHome
and the last section says any method can be invoked.
I packaged the openAMF jar file within my ear that also contains my EJB's, the openAMF advanced gateway was added to my web.xml for my webapp :
<servlet>
<servlet-name>AdvancedGateway</servlet-name>
<display-name>AdvancedGateway</display-name>
<description>AdvancedGateway</description>
<servlet-class>org.openamf.AdvancedGateway</servlet-class>
<init-param>
<param-name>OPENAMF_CONFIG</param-name>
<param-value>/WEB-INF/openamf-config.xml</param-value>
<description>Location of the OpenAMF config file.</description>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AdvancedGateway</servlet-name>
<url-pattern>/gateway2</url-pattern>
</servlet-mapping>
Remember if your openAMF.jar is deployed in a separate war file the stubs to your EJB's must be in the web-inf-lib directory of the war file that will contain the openAMF jar or the openAMF EJB invoker won't be able to call your EJB's. For a first test I'd recommend putting everything in 1 ear.
Finally to call my service from flash using actionscript 2.0
trace("serviceCode constructor");
NetDebug.initialize();
gatewayURL = "http://localhost:7001/EAT/AdministrationServiceWebApp/gateway2";
myBeanService = new Service( gatewayURL, null, "AdministrationService", null, null );
var request = new Object;
request.newPassword= "foo12345";
request.userId="pddz2";
trace("Bean test started");
var pendingCall:PendingCall = myBeanService.resetPassword(request);
pendingCall.responder = new RelayResponder(this, "onResult", "onStatus");
public function onResult(resultObject:ResultEvent):Void
{
trace("string: " + resultObject.result + " was returned by onResults");
trace ("description: " + resultObject.result.description);
trace ("statusCode: " + resultObject.result.statusCode);
trace ("uiMessage: " + resultObject.result.uiMessage);
}
public function onStatus(faultObject:FaultEvent):Void
{
trace("Status is " + faultObject);
}
I'll put together a real ear file with source code at some point that can be deployed to jboss or something, right now I'm a weblogic guy due to my client so the example will be based on free time :) Feel free to ask questions if you get stuck as I know the docs are a bit sparse.
Thanks a million to the openAMF team, they've done a top notch job, now if someone can port it to .NET ...... :)
This was helpful; you're quite right to thank the openamf team for a job well done. But I hope they will place priority on documentation rather than a .Net port.
Posted by: C. Brevard | August 25, 2005 at 01:50 PM
Well whenever I get some time I may start contributing, I'd like to have good docs and I'd also like some more features so as support of the service browser from the flash IDE that lets you browse the available features of a service.
Posted by: Grant Davies | August 26, 2005 at 04:19 PM