Wednesday, July 12, 2006

Flex: The World's Simplest Example of RemoteObject

Here is a very, very simple example of using the RemoteObject RPC services in Flex 2 to invoke methods on a Java object. I came up with this because I was struggling to figure out all the stuff needed to do this. In theory, it's pretty simple, but there are a number of components to deal with, and they all get put in different places on the server, and a bunch of those places look very similar to other places on the server.

Introduction


It was especially difficult for me because I'm new to Flex, and I'm coming at it from a server-side background in Java. I don't care about making pretty user interfaces (that's someone else's job) - I'm the guy who has to make the server code work. However, most of the documentation assumes that you're coming at it from the other end - the client side.

I couldn't find any simple examples of using RPC in Flex 2.0. I foolishly started with Flex 1.5 example and wasted a bunch of time updating the syntax in it in order to get it to compile.

After I got that to compile (from the command line - I'm old school), it wouldn't run. After I got the Flash debugger working, I could see that the messaging destination didn't exist, but I couldn't figure out why. So far as I could tell, I had configured it correctly, but there was no indication that things were making it to the server. Finally, I gave up my command line and put the MXML file on the server, and just let the web-tier compiler do it for me.

And, it just worked! The documentation makes reference to using the SDK compiler versus the web-tier compiler, but it just didn't click with me. But, it was still more complicated than I needed. So, I created the following, to prove that I could do it, and that I knew all the voodoo needed.

I will assume that you have the Flex Data Services demo server with Jrun installed an running. I will specify all paths from the root of the jrun server.

Java Code


Let's start with the simplest function in a Java file - basically, "hello world."


public class SimpleRemoteObject
{
public void writeToConsole(String msg)
{
System.out.println("SimpleRemoteObject.write: " + msg);
}
}


This will just write a message to the server console window. (We don't even have to use any fancy Java logging.)

Compile that file and put the SimpleRemoteObject.class file in the directory jrun4/servers/default/samples/WEB-INF/classes on the server. (Note that since the class is in the unnamed, default package, we put the class file in classes, not a subdirectory.)

Flash Client


Now, we need a simple Flash app. Here's a simple MXML file:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="#FFFFFF"
initialize="initApp()">
<mx:Script>
public function initApp():void {
}

public function writeToConsole():void {
remoteObj.writeToConsole("hello from Flash client");
}
</mx:Script>

<mx:RemoteObject id="remoteObj" destination="sro">
<mx:method name="writeToConsole"/>
</mx:RemoteObject>

<mx:Form>
<mx:FormItem>
<mx:Button label="Write To Server Console" click="writeToConsole()"/>
</mx:FormItem>
</mx:Form>
</mx:Application>

Create a directory called sro under jrun4/servers/default/samples and put the MXML file there.

Now, we can compile the file by loading it in the browser with a URL like:
http://192.168.123.130:8700/samples/sro/SimpleRemoteObject.mxml
(The key is that the file is under /samples/sro based on where we copied the file.)

Don't click the button yet! We still have to configure the FMS destination. Just make sure it compiles correctly.

Configure the Server


Add the following XML code to jrun4/servers/default/samples/WEB-INF/flex/remoting-config.xml. Just put it within the service tag for the remoting-service - e.g., near one of the other FMS destinations.

<destination id="sro">
<properties>
<source>SimpleRemoteObject</source>
</properties>
</destination>

And now, if you press the "Write to Server Console" button, the message, "hello from Flash client" will appear in the Jrun server window.

That's it. It really is as easy as Adobe says it is...
once you figure it all out.

enjoy,
Charles.

11 comments:

Karthik said...

hi
i did what you told but i am getting script error i.e url error

when i run in Internet explorer i get this type of error
[RPC Fault faultString="SimpleRemoteObject (Unsupported major.minor version 49.0)" faultCode="Server.Processing" faultDetail="null"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()
at mx.rpc::Responder/fault()
at mx.rpc::AsyncRequest/fault()
at ::NetConnectionMessageResponder/NetConnectionChannel.as$33:NetConnectionMessageResponder::statusHandler()
at mx.messaging::MessageResponder/status()

Charles Anderson said...

The "(Unsupported major.minor version 49.0)" means your code was compiled on a newer version of the JDK than you're running it on - e.g., compiled with 1.5 and running on 1.4. (I don't know the exact version numbers based on the "49.0").

Madhavi said...

hi
I have tried everything as U told, but I am getting "send failed" error when I click on the button

[RPC Fault faultString="Send failed" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 503: url: 'http://localhost:8700/samples/messagebroker/amf'"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()
at mx.rpc::Responder/fault()
at mx.rpc::AsyncRequest/fault()
at mx.messaging::ChannelSet/::faultPendingSends()
at mx.messaging::ChannelSet/channelFaultHandler()
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.messaging::Channel/mx.messaging:Channel::connectFailed()
at mx.messaging.channels::PollingChannel/mx.messaging.channels:PollingChannel::connectFailed()
at mx.messaging.channels::AMFChannel/mx.messaging.channels:AMFChannel::statusHandler()

Arun Kumar Madas said...

I had been breaking my head to get this work and this is such a sweet post... i love it...It works like a charm...

sanjeev said...

How to get this work with jboss?

Sanjeev Rajput

sanjeev said...

How to get this work with jboss?

Sanjeev Rajput

TallPaul said...

I had the same "(Unsupported major.minor version 49.0)" error and BELIEVE I have found the true answer.

JRun is using JRE 1.4.2_12 while my byte code is compiled with 1.6 update 6. So why is Jrun using 1.4? Check this file out:
C:\lcds\jrun4\bin\jvm.config

In there, it says that JRun will BY DEFAULT use the JRE in this directory:
java.home=c:/lcds/UninstallerData/jre

Sure enough, java.exe exists in that directory. When I open a command prompt window and go to that directory and do a java - version, here is what I get:

C:\lcds\UninstallerData\jre\bin>java -version
java version "1.4.2_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_12-b03)
Java HotSpot(TM) Client VM (build 1.4.2_12-b03, mixed mode)

So Jrun is forced to use JRE 1.4.2_12, instead of the more up-to-date 1.6 I have installed on my system!!! Therefore, it can't interpret the 1.6 bytecode.

To me, this is incredibly bad logic from the JRun developers. The default should be to use whatever the user has installed (in my case 1.6 update 6), and if NO other JRE is found or the JRE found is OLDER than 1.4.2_12, THEN use 1.4.2_12.

So what I did was to comment out the java.home line above, save the .config file, and re-start JRun. The 49.0 error went away, but I have yet to get the Java object to write the text message out. No errors, but then again no pop-up windows either from the System.out.println call. Ideas?

BTW, this is on LCDS 2.5.1. The most current LCDS on Adobe's site is 2.6, which does NOT allow the installation of Jrun. Instead it only allows the installation of Tomcat and J2EE. If you Google LiveCycle Data Services 2.5.1 you should be able to find the Adobe link.

I would LOVE to see an example using J2EE instead of JRun. Would it be exactly the same?

Hope this helps!

Paul

TallPaul said...

Oops! Never mind on the pop-up window! :-) I don't know what I was thinking. I see the "SimpleRemoteObject.write: hello from Flash client" in the LiveCycle Data Services command prompt window... that's the proof it works! So problem solved!

Paul

TallPaul said...

"BTW, this is on LCDS 2.5.1." I meant 2.51 :-)

Manuel said...

hey, can u help me ?

I have a problem...I've made a app with RemoteObject local in mi PC, but, when I upload the .war file to the server it doesnt work.....

:S

I dont know the reason.... could u help me?

Charles Anderson said...

Sorry, Manuel, but I can't help you. I posted this nearly 5 years ago, and I haven't done any Flex since then. I suspect that both the server and client sides of Flex have changed considerably since then.

Charles.