Externalizing Service Configuration using BlazeDS and LCDS

A typical source of confusion when developers start working with RemoteObject or other BlazeDS/LCDS related classes is where and most importantly *when* the configuration of your services is being read.

The question often arises after an application stops working when you move it to another server. This is one of the most frequently asked questions related to BlazeDS and LCDS, so I figured I would answer it here. There is nothing really new in this post, but hopefully this will be a good point of reference.

When you create a new BlazeDS or LCDS project in Flex Builder, you are typically told to select J2EE as the “Application Server Type” and then check “use remote object access service”. This adds a compiler argument pointing to the location of your services-config.xml. If you check the Flex Compiler properties of your Flex Builder project, you’ll see something like this:

-services “c:\blazeds\tomcat\webapps\samples\WEB-INF\flex\services-config.xml”

When you then compile your application, the required values of services-config.xml are baked into the SWF. In other words, services-config.xml is read at compile time and not at runtime as you may have thought intuitively. To abstract things a little bit, you can use tokens such as {server.name}, {server.port}, and {context.root} in services-config.xml. However, {context.root} is still substituted at compile time, while {server.name} and {server.port} are replaced at runtime using the server name and port number of the server the SWF was loaded from (which is why you can’t use these tokens for AIR applications).

Fortunately, the Flex SDK provides an API that allows you to configure your channels at runtime and entirely externalize your services configuration from your code (you definitely don’t want to recompile your application when you move it to another server). At a high level, it works like this:

var channelSet:ChannelSet = new ChannelSet();
var channel:AMFChannel = new AMFChannel("my-amf", "http://localhost:8400/lcds-samples/messagebroker/amf");
channelSet.addChannel(channel);
remoteObject.channelSet = channelSet;

This is still not what we want because the endpoint URL is still hardcoded in the application. At least in this case it’s obvious that it is. So, the last step is to pass that endpoint URL value at runtime. There are a number of ways you can pass values to a SWF at runtime (flashvars, page parameters, etc). The approach I usually use is to read a configuration file using HTTPService at application startup. That configuration file includes (among other things) the information I need to programmatically create my channel set at runtime. Here is a basic implementation:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	applicationComplete="configSrv.send()">

	<mx:Script>
	<![CDATA[

	import mx.controls.Alert;
	import mx.messaging.channels.AMFChannel;
	import mx.messaging.ChannelSet;
	import mx.rpc.events.ResultEvent;

	private var channelSet:ChannelSet;

	private function configResultHandler(event:ResultEvent):void
	{
		var xml:XML = event.result as XML;
		var amfEndpoint:String = "" + xml..channel.(@id=="amf").@endpoint;
		if (amfEndpoint == "")
		{
			Alert.show("amf channel not configured", "Error");
		}
		else
		{
			channelSet = new ChannelSet();
			var channel:AMFChannel = new AMFChannel("my-amf", amfEndpoint);
			channelSet.addChannel(channel);
			ro.channelSet = channelSet;
			ro.getProducts();
		}
	}

	]]>
	</mx:Script>

	<mx:HTTPService id="configSrv" url="config.xml" resultFormat="e4x" result="configResultHandler(event)"/>

	<mx:RemoteObject id="ro" destination="product"/>

	<mx:DataGrid dataProvider="{ro.getProducts.lastResult}" width="100%" height="100%"/>

</mx:Application>

The configuration file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<config>
	<channels>
		<channel id="amf" endpoint="http://localhost:8400/lcds-samples/messagebroker/amf"/>
	</channels>
</config>

NOTE: With that type of runtime configuration in place, you can create plain Flex Builder projects (you can select None as the application server type).

This particular example is not extremely flexible. It assumes I will always work with an AMF channel and therefore the only thing my application needs to know at runtime is the AMF channel endpoint URL. For RemoteObject that’s a fairly safe bet, however for messaging-related classes (Producer and Consumer), you may also want to externalize the type of channel you use (AMF Polling, long polling, streaming, RTMP, etc.). Before you start creating that kind of dynamic configuration system, you may want to take a look at the Flex ActionScript framework that does that very well.

  • stef

    thank you christophe – very helpful! SB

  • Astor Digital

    We actually had the requirement to read these parameters(ie http://uniqueserver:8080) via flash vars, then construct the secure amf channel.

  • Just to note that the Swiz framework includes very nice support for dynamic ChannelSet creation.

  • Hi Brian,
    I looked at Swiz and I like it as I hope you can tell from the blog post. You guys are doing a really great job. On this particular topic of externalizing service configuration, I didn’t see a built-in solution to externalize the configuration from the source code (I may have missed it as I only had a limited amount of time to explore the framework). In this example, the port and context root are still hard coded.
    Also, at first glance, I didn’t see the real benefit of using DynamicChannelSet compared to the standard ChannelSet class. For example, in my Beans.xml I can replace:

    <DynamicChannelSet id="myAmfChannel">
    <serverPort>8400</serverPort>
    <contextRoot>/lcds-samples</contextRoot>
    </DynamicChannelSet>

    <mx:RemoteObject id="contactService" destination="contacts" channelSet="{myAmfChannel}"

    with

    <mx:ChannelSet id="channelSet">
    <mx:AMFChannel id="amf" url="http://localhost:8400/lcds-samples/messagebroker/amf"/&gt;
    </mx:ChannelSet>

    <mx:RemoteObject id="contactService" destination="contacts" channelSet="{channelSet}"/>

    The second approach uses the SDK classes and doesn’t have a dependency on services-config.xml either. Are there additional benefits in using DynamicChannelSet?
    Thanks,
    Christophe

  • aivilo

    Hi Christophe
    We are developing a flex chart componment like Yahoo finance. but when we connected it with live datafeed, we experience serious lagging probelm. It got worse when we add technical indicators to it. We have asked for suggestions from Adobe HK. They recommend us to reduce the frequency of datafeed var numNull:int = Math.floor( (1000/9) /(1000/24)) / 2; to avoid accumulation of refresh events. But performance is prime to us and we need to use realtime data. Could you give us some suggestions on how to handle this problem. We are so impressed with your traderdesktop. It would be grateful if you could you give us an email so that we could show you our development? Thanks.

  • Pingback: Flex Monkey Patches » Blog Archive » Rubbernecker’s Review - Week 31 - (Adobe Flex/Flash/AIR/LCDS Blog post recap)()

  • Christophe,

    I always enjoy reading your posts. I recently had that same problem since I was trying to install BlazeDS on a remote server and every single tutorial on the internet I found was about installing it and running it locally. I made a post that had to do with that on my blog althought you explained it a lot better than I did. Check it out if you’d like: BlazeDS & WSDL Introspection.

  • Vineet Bhatia

    Hi Christophe,

    If we remove services-config.xml from compiler arguments we get “MessagingError message=’Destination ‘Destination_name’ either does not exist or the destination has no channels defined (and the application does not define any default channels.”

  • Pingback: A simple approach to Flex ColdFusion integration « Greg Wilson’s Ramblings()

  • Pingback: One more thing… « M@ Blog()

  • How to NOT ignore java beans read only properties in Java?

    As stated in LCDS AMF serialization documentation, the read-only properties of a java bean are ignored in the AMF serialization process. What do I need to do so that the read only properties are also serialized?

    Any link or documentation would be helpful

  • schujfi

    If you externalize your services, don’t forget to make the Server available to the clients placing the crossdomain.xml file in the root server.

  • Paulo Fabiano Langer

    Hi Christophe, nice post :)
    Could you give me some tips about my issues?
    I have a main java web application that needs to send messages (jms) to my flex dashboard application. Both applications are in the same server but my blazeDS is running in other server under tomcat.
    How could I config both applications to produce and consume messages using the remote blazeDS ?
    Some people told me to use JNDI but I don´t know how very well that API.
    Thanks

  • Pingback: Christophe Coenraets » Blog Archive » Building a Flex Application with the Parsley Framework()

  • thank you admin good fluser

  • I cannot believe this will work!

  • Pingback: Externaliser la configuration de ses remoteObjects. | Matsiya()

  • Brian Bonner

    I would like have a linux server running as our continuous integration.

    We build locally using Flexbuilder on windows, but we cant get linux to compile any services. Any ideas???

  • Bharat

    Hi Christophe,

    I am developing an application using LCDS and J2EE.
    What are the steps required to build an application.
    What all do we need?

  • Raghu

    Hi Christophe,

    I have developed an application using Flex , LCDS and J2EE. The application works very well when deployed in my local system. When I deploy the application in another system, i see that the LCDS call are not happening. What might the resolution for this issue?

    Thank You

  • Nikos Katsikanis

    Awesome code Sir, I guess I can delete the following code from my service-config.xml

    <endpoint uri="//secret

    since I define the stuff in my extra service file on my server?

    thanks for any tips

  • program yükle Good admin than you

  • Pingback: Constantiner's blog()

  • Use it with a lot of caution!!!!

    It seems to work, but the code really doesn’t works when you open several channels at the same time. You will get a lot of “Channel disconnected” exceptions.

    I think the ideas exposed here are very very useful and very they are well explained. Thanks a lot. Though users could have problems if they use your code without any correction.

    Pablo.

  • Hi again!

    Problem solved! Define and initialize an unique static ChannelSet and apply it to all created remote objects.

    I guess ChannelSet (or AMFChannel) is a limited System resource. So you can’t open a lot of channels simultaneously. But you can reuse the same channel for all remote objects.

    That is based on my experience. I can’t justify that.

    Thanks a lot Christopher!

  • Hi Cristophe,

    are you aware that you can use relative URL’s for the endpoints, too? The URL is resolved relative to the url where the Flex file was loaded from. This solves the “my flex file moved to another server” problem, without any extra complexity.

    Of course, this only works if the file is access from the server.

    Regards,

    Allard

  • Santhi

    I am trying Flex client configuration for BlazeDS in SunOneWebserver.
    I am getting error like this:
    faultcode=”Client.Error.MessageSend”
    faultDetail=”Channel.Connect.Failed error NetConnection.Call.Failed.

  • Priyabrat Mohapatra

    Hi Vineet,

    I could compile and execute this sample code without specifying -service option to mxmlc (sdk version 3.5).

    But yes, BlaseDS throws runtime exceptions while initializing MessageBrokerServlet if I start it

    without services-config.xml in WEB-INF/flex
    Exception: flex.messaging.config.ConfigurationException: Please specify a valid ‘services.configuration.file’ in web.xml.
    You specified ‘/WEB-INF/flex/services-config.xml’. This is not a valid file system path reachable
    via the app server and is also not a path to a resource in your J2EE application archive.
    or
    removing the element from services-config.xml [as suggested by Nikos Katsikanis“]
    Exception: flex.messaging.config.ConfigurationException: Attribute ‘endpoint’ must be specified for element ‘channel-definition’.

    or
    not having a channel-definition in services-config.xml that is referred by any element in remoting-config.xml.
    Exception: flex.messaging.config.ConfigurationException: channel not found for reference ‘my-amf’.

    I could simulate the kind of client side error what you get i.e.
    [RPC Fault faultString=”[MessagingError message=’Destination ‘echoServiceDestination’ either does not exist or the destination has no channels defined (and the application does not define any default channels.)’]” faultCode=”InvokeFailed” faultDetail=”Couldn’t establish a connection to ‘echoServiceDestination'”]
    by removing applicationComplete=”configSrv.send()” from the main application tag.

    But the NetConnection client side error i.e.
    [RPC Fault faultString=”Send failed” faultCode=”Client.Error.MessageSend” faultDetail=”Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 500: url: ‘http://localhost:8090/blazeds/messagebroker/amf'”]
    occurs in all other cases viz when there is run time exception when initializing MessageBrokerServlet or wrong endpointurl (say port as 8090 instead of 8080) specified in config.xml as might be the case with Shanthi.

  • Bedava herşey burada

  • Kral oyunun en mükkemmel sitesi

  • Jateen

    I am getting total time in MessagePefirmanceUtils as
    -ve. Is there any compatability issues of lcds with Java 1.6

  • Thanks for the valuable information. Recently i tried switching my applications to a different server and found the BlazeDs annoying. Now i am running in my new server. Thanks for the solution.

    Thanks
    Collin paul
    Learn Forex

  • Since i’m just getting started, can you suggest a good beginner’s tutorial on this subject?

  • AAP

    Hi,
    I am new to Flex, and I appreciate your information here.
    However, I am in a fix as to how you supply “destination” information if you do not have a services-config.xml.

    I am trying to setup a coldfusion-flex project and I am getting an error “No destination with id ‘product’ is registered with any service.”

    public var productsRO:RemoteObject;
    public function ProductsService()
    {

    var channelSet:ChannelSet = new ChannelSet();
    channelSet.addChannel(new AMFChannel(“ProductsService”,”http://cfweb.dev/flex2gateway/”));

    productsRO = new RemoteObject();
    productsRO.channelSet = channelSet;
    productsRO.destination = “product”;
    }

    I am using the above code for setting up my Product_RO

    I will greatly appreciate it if you can provide an answer for this, as I would like to decouple from DEV machine’s coldfusion setup vs Prod-server CF setup

    Thanks,
    AAP

  • Just an add on from the Brian comment. The Swiz system has been updated and is even better now. Thanks for the info.

  • truly one of a kind! thanks

  • forex Trading is not easy. You can become a good forex trader though dedication and by treating forex trading as you would any other skill. The reality is that it is hard work and must be treated with the same amount of seriousness as you would any other career.

  • How about connecting from another server and not form inside tomcat? I can’t point to a generic gateway like I can in php, there is no context root so the http://blahblah.com/context-root/messagebroker/amf is missing a part.
    Any insight on this?

  • Dre

    This works fine when I run the app in Flash Builder, but I get a ‘file not found’ error when I build the app and deploy it, even though I see the file in my ‘config’ directory.

    Is there some additional permission and/or config to get the Flex app to read the file when the app is deployed? I don’t have this problem with svg files I’ve embedded from an ‘assets’ directory.

  • Rodrigo

    Thanks a lot,
    it’s a good solution for flashdevelop users, because flashde

  • Rodrigo

    Thanks a lot,
    it’s a good solution for Flashdevelop users too…

  • Chris

    Life-saving Information! Thank you.

  • Thank you for the great info,

    Incredible – never seen before Forex software just launched!

    “Auto Trend Forecaster”

    http://autotrendforecaster.yolasite.com/

    This is one the most profitable
    Forex Trend indicators you can get today!
    !

  • Get your own PR 9 Edu blogs and backlinks. Get listed on google first page for your keywords in a matter of hours!

    Visit: http://edu-blogs.yolasite.com

    Get yours whilst special offer lasts

  • Hi Christophe,

    Another (easy) way to get ‘run time flexibility’ in an AIR application is:
    – compile with the services-config.xml
    – leave the ‘{server.name}’ in tact in services-config.xml
    – at run time, search/replace ‘ServerConfig.serverConfigData’ with what you want (e.g. connecting to a different server)

    // Search/replace server in services-config compiled
    var serverConfigData:XML = ServerConfig.serverConfigData;

    // Convert to String and replace {server.name} with actual server
    var serverConfigDataAsString:String = serverConfigData.toXMLString();
    serverConfigDataAsString = serverConfigDataAsString.split(“{server.name}”).join(serverName);
    ServerConfig.serverConfigData = new XML(serverConfigDataAsString);

    From here on the AIR application behaves as if you had the server name hard coded in the services-config.xml.

  • This is truly one of the best blogs I have ever come across. Very well written, precise and to the point. Thanks to the author for this brilliant share.

  • Just bookmarked this link in my browser. I will definitely visit this site later to read some more quality blogs. Thanks.

  • flexerMan

    God bless you Christophe Coenraets.

  • Praveen

    I like your work in Flex community ..
    I’m wondering if we can read an external xml data and use it in Bean configuration (Beans.mxml) before swiz initialization. Making endpoint configuration and channel switching from amf to amfsecure much easier ??

  • Seppe Staes

    Very useful blogpost. Do you know whether it’s possible to enable “mx.messaging.messages.MessagePerformanceUtils” using the above method? It’s a read-only property.

  • Seppe Staes

    Very useful blogpost! However, do you know whether it’s possible to set values for recordMessageTimes/Sizes using this method (used in conjunction with mx.messaging.messages.MessagePerformanceUtils)? They seem to be read-only values on Channel. Best regards, Seppe

  • “This blog is really very interesting and easy to understand the information provided in it. It is very nice to view this blog and it’s nice to see the best information cited here.
    Thank you.”

  • Shally Dhar

    Hi Christophe,
    We are doing the same in our application. Its very strange that this works for the AMF channel but not for the RTMP since we are using Server Push in our application. So, we need to use the RTMP port.

    I am configuring the channel during application launch in a custom class as under:
    public static function get rtmpChannelSet():ChannelSet
    {
    var cs:ChannelSet = new ChannelSet();
    var url:String = protocol + “//” + hostName + “:” + rtmpPort;
    var rtmpChannel:RTMPChannel = new RTMPChannel(“myRtmp”,”rtmp://localhost:2038″);

    cs.addChannel(rtmpChannel);

    return cs;
    }
    Then when I call the dataservice.fill method, I assign the above channelset and destination as under:

    _actionDataService = new DataService(“action”);
    _actionDataService.channelSet = ServiceManager.rtmpChannelSet;
    _actionDataService.fill(_acActionStatus, acInstrument);

    But I get the following fault:
    Channel.Connect.Failed error undefined url:’rtmp://localhost:2038′

    I am not sure why this is working for AMF and not for RTMP.

    Any help will be much appreciated.

    Thanks and Regards,
    Shally

  • samuel

    Hi Christophe,
    Thanks for sharing this useful config info. Can we pass settings/url in command line arguments instead of reading from config file, is it possible in flex?

  • samuel

    Can we set proxy-configurations at runtime and connect

  • Great beat ! I wish to apprentice at the same time as you amend your site, how could i subscribe for a weblog site? The account aided me a acceptable deal. I had been a little bit acquainted of this your broadcast provided vibrant clear idea

  • Thanks a lot for giving everyone an extremely remarkable opportunity to read in detail from this blog. It is always very awesome and full of a great time for me personally and my office co-workers to visit your website particularly three times in a week to study the new items you have. And indeed, I am always fascinated for the remarkable methods you serve. Certain 2 areas on this page are certainly the most effective I have had.

  • I’m curious to find out what blog system you are utilizing? I’m experiencing some small security problems with my latest site and I’d like to find something more safe. Do you have any suggestions?

  • What a information of un-ambiguity and preserveness of precious experience oon the topic of unpredicted
    emotions.

  • Each office will become more solid, the interior is easy to emphasize the many
    kinds of shelving. – Lumber (amount depends on what plan you followed).
    Consider employees such as your waiters and give them enough room to move around to serve diners as quickly
    as possible and with ease and comfort.

  • We’re a group of volunteers andd opening a new scheme in our community.
    Yourr website prtovided us with valuable info to work
    on. You’ve done an impressibe joob and oour entire community will
    be grateful to you.

  • I took it one step at a time and six months later I had a nice looking
    dresser and an extensive amount of knowledge that I could
    use on my next woodworking project. If you fail
    to do these things, you could end up with spray foam on furniture
    and walls. Plus, it’s for scrapbooking so it’s already color coordinated.

  • 50 shots include the Washington Apple, Royal F-(wait, can I say that.
    The rails also serve as a framework for the overall support system.
    This template is entirely blank except for the dotted borders around each card.

  • Terrific article! This is the type of information that are supposed to be shared aacross the net.
    Shame on the seek engines for no linger positioning this publish upper!
    Come oon over and discuss with my site . Thank you =)

  • In the winter, the dog’s body heat is what helps to heat the house.
    Know what drives him crazy (in a good way) and use that to your advantage.
    This free gift from nature can be turned into functional items and works of art.

  • Ideally, you want your bed between one and two feet tall.
    and by not stepping around your plants reduces soil compaction,
    resulting in healthier roots and plants. When setting the footprint of your garden, think about where the water will run
    off.

  • Howdy! I simply wish to give you a big thumbs up for the great info you have
    right here on this post. I will be returning to your site for more soon.

    Hi, i think that i saw you visited my site thus i came to
    “return the favor”.I’m trying to find things to enhance my web site!I suppose its ok
    to use some of your ideas!!
    \

  • Hi there!, I think website looks good written. Love the art!

  • After looking at a handful of the blog posts on your site, I reaally appreciate your
    way of writing a blog. I saved as a favorite it to my bookmark webpage list
    and will bbe checking back in the near future.
    Take a look at myy website too and let me know what you think.

  • This will make the other person feel really good and create some
    interest in you. As it’s a first date, make small talk.

    Any live webcam chat room is simply about this.

  • Je suis pressé de lire votre prochain poste

  • XXX

    Vachement intéressant : selon mօi ce poste devrait intéresser maa
    meuf

  • Great work! This is the kind of information that are meant to be shared around the web.
    Disgrace on the seek engines for now not positioning this publish higher!
    Come on over and discuss with my site . Thanks =)

  • Mince je comptais justement écrire un post pareil au
    tiens

  • These are normally rather small units which have been created to present feasible consuming h2o when you are not
    near a taken care of drinking water supply (untreated drinking water
    sources include lakes, rivers, streams, and many others.
    Today, The brand is based in San Leandro, north face
    sale, near its corporate sibling, Jan – Sport.
    If you find the idea of snakes in the toilet a good means to scare your friends at Halloween, there are
    toilet covers with a snake motif just for that purpose.

  • Link exchange is nothing else except it is simply placing the other person’s
    web site link on your page at appropriate place and other person will also do same for you.

  • Bon, je n’ai pas eu le temps de terminer de regarder cependant je reviendrai dans la journée

  • Inspiring quest there. What happened after?
    Thanks!

  • When you are overweight and feeling hungry all the
    time, your body is craving specific nutrients not found in traditional diets especially diets high in empty calories.
    But this is easier said than done, most people who don’t exercise tend
    to use the excuse I haven’t got time to exercise my life
    is too busy. Furthermore, eating food items having lots of nourishment
    in addition to small amounts of calories is extremely helpful with removing excess fat too.

css.php