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.

65 Responses to Externalizing Service Configuration using BlazeDS and LCDS

  1. stef March 23, 2009 at 1:38 pm #

    thank you christophe – very helpful! SB

  2. Astor Digital March 24, 2009 at 1:05 pm #

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

  3. Brian Kotek March 24, 2009 at 5:09 pm #

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

  4. Christophe March 24, 2009 at 8:46 pm #

    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

  5. aivilo March 26, 2009 at 12:49 am #

    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.

  6. Dustin S March 27, 2009 at 6:04 pm #

    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.

  7. Vineet Bhatia April 3, 2009 at 9:11 am #

    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.”

  8. How to NOT ignore java beans read only properties in Java? May 13, 2009 at 2:18 am #

    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

  9. schujfi May 17, 2009 at 9:45 am #

    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.

  10. Paulo Fabiano Langer June 29, 2009 at 3:49 pm #

    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

  11. bedava film izle July 28, 2009 at 4:12 am #

    thank you admin good fluser

  12. Lucie-Mueller July 29, 2009 at 1:39 pm #

    I cannot believe this will work!

  13. Brian Bonner August 19, 2009 at 11:40 pm #

    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???

  14. Bharat August 26, 2009 at 9:21 am #

    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?

  15. Raghu November 4, 2009 at 9:07 pm #

    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

  16. Nikos Katsikanis November 13, 2009 at 3:23 pm #

    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

  17. Program yükle November 21, 2009 at 12:08 pm #

    program yükle Good admin than you

  18. pablo February 2, 2010 at 4:59 pm #

    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.

  19. pablo February 2, 2010 at 8:05 pm #

    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!

  20. Allard Buijze February 25, 2010 at 4:50 am #

    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

  21. Santhi April 26, 2010 at 8:38 pm #

    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.

  22. Priyabrat Mohapatra July 25, 2010 at 6:42 am #

    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.

  23. Bedava July 31, 2010 at 6:45 am #

    Bedava herşey burada

  24. Kral oyun August 1, 2010 at 10:20 am #

    Kral oyunun en mükkemmel sitesi

  25. Jateen August 23, 2010 at 4:24 am #

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

  26. Collin August 26, 2010 at 5:34 am #

    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

  27. Provenge November 5, 2010 at 9:44 am #

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

  28. AAP November 6, 2010 at 6:32 pm #

    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

  29. Richard in Paris November 18, 2010 at 10:00 am #

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

  30. one of a kind January 28, 2011 at 9:58 am #

    truly one of a kind! thanks

  31. nance fray February 21, 2011 at 7:06 am #

    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.

  32. Gustav Xyrer February 24, 2011 at 12:18 pm #

    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?

  33. Dre March 31, 2011 at 1:31 pm #

    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.

  34. Rodrigo April 28, 2011 at 8:43 am #

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

  35. Rodrigo April 28, 2011 at 8:44 am #

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

  36. Chris April 29, 2011 at 6:05 am #

    Life-saving Information! Thank you.

  37. forex man June 15, 2011 at 7:54 pm #

    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!
    !

  38. mike June 20, 2011 at 3:03 am #

    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

  39. Paulus de B. July 2, 2011 at 10:07 am #

    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.

  40. wound bandages September 8, 2011 at 1:40 pm #

    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.

  41. aquacel September 27, 2011 at 8:18 am #

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

  42. flexerMan October 11, 2011 at 3:24 am #

    God bless you Christophe Coenraets.

  43. Praveen October 25, 2011 at 12:01 pm #

    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 ??

  44. Seppe Staes February 20, 2012 at 8:38 am #

    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.

  45. Seppe Staes February 20, 2012 at 8:43 am #

    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

  46. dissertation help UK May 23, 2012 at 3:13 pm #

    “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.”

  47. Shally Dhar June 27, 2012 at 6:49 am #

    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

  48. samuel August 22, 2012 at 4:37 pm #

    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?

  49. samuel August 22, 2012 at 5:16 pm #

    Can we set proxy-configurations at runtime and connect

  50. flashoyunz January 18, 2013 at 4:21 pm #

    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

  51. Keli Borlace January 19, 2013 at 12:08 am #

    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.

  52. bread recipe July 20, 2013 at 10:40 am #

    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?

  53. Prodermagenix October 20, 2013 at 8:02 pm #

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

  54. workbench plans April 10, 2014 at 2:28 pm #

    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.

  55. شركه رش مبيدات April 12, 2014 at 2:16 pm #

    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.

  56. diy furniture April 14, 2014 at 6:56 pm #

    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.

  57. deck plans April 15, 2014 at 8:39 am #

    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.

  58. cheap logbook loans April 17, 2014 at 2:56 pm #

    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 =)

Trackbacks/Pingbacks

  1. Flex Monkey Patches » Blog Archive » Rubbernecker’s Review - Week 31 - (Adobe Flex/Flash/AIR/LCDS Blog post recap) - March 26, 2009

    [...] Externalizing Service Configuration using BlazeDS… (from Christophe Coenraets) [...]

  2. A simple approach to Flex ColdFusion integration « Greg Wilson’s Ramblings - April 17, 2009

    [...] had recently read Christophe Coenraets blog post title, “Externalizing Service Configuration using BlazeDS and LCDS” which addresses the same issue with configuring Flex applications to use BlazeDS or [...]

  3. One more thing… « M@ Blog - April 19, 2009

    [...] documentation to figure something out but Christophe Coenraets came to the rescue with a post on externalizing your service configuration that has it covered. Posted in BlazeDS, Flex. Tags: BlazeDS, Flex, LCDS. No Comments [...]

  4. Christophe Coenraets » Blog Archive » Building a Flex Application with the Parsley Framework - July 16, 2009

    [...] Note: In a real life application, you would not want to hardcode the endpoints of your services in your source code. You could use the XML configuration option to configure your endpoints in a more “externalized” fashion. More on this topic here. [...]

  5. Externaliser la configuration de ses remoteObjects. | Matsiya - August 10, 2009

    [...] À consulter sans attendre : l’article. [...]

  6. Constantiner's blog - January 19, 2010

    Dynamically loaded BlazeDS configuration in Flex applications…

    For people who wants to use server configuration (I mean channels, endpoints and remoting destinations from BlazeDs/LCDS services-config.xml and remoting-config.xml) loaded in runtime instead of common practice with reading configs in compile time Cris…

Leave a Reply