You are on page 1of 6

Migrating from BlazeDS to GraniteDS | Granite Data Services

http://granitedataservices.com/migrating-from-blazeds-to-graniteds/

What is GraniteDS?

Enterprise Services

Blog

Contact

Migrating from BlazeDS to GraniteDS


There are many reasons why you would want to switch to GraniteDS from BlazeDS, as described in the following presentation (available on SlideShare):

GRANITEDS VS. BLAZEDS

The technical reasons can be more or less sorted in 3 main groups : 1. Benefit from a better messaging scalability by using the asynchronous servlet support of your application server (for example with the APR native library of Tomcat or a Servlet 3 compliant container) 2. Avoid the famous LazyInitializationException and similar errors when serializing JPA detached objects 3. Using the advanced data management features These 3 reasons imply different levels of complexity of the migration. This post is going to show how to implement 1 and 2, this is quite easy and mainly implies a few changes in the configuration. Implementing 3 is a bit more involving and greatly depends on your application architecture, however in general it will allow massive cuts in the usual boilerplate code needed in typical data-intensive applications.

Using Gravity support for asynchronous processing


Starting from a working BlazeDS project, here are the steps that are needed to use GraniteDS : Replace the BlazeDS libraries and their dependencies by granite.jar in WEB-INF/lib Configure the GraniteDS servlets in web.xml (and remove the BlazeDS MessageBroker) Configure the messaging destination in WEB-INF/flex/services-config.xml (this file follows the same format as default BlazeDS configuration files) but use the org.granite.gravity.channels.GravityChannel implementation for the messaging channel Add the granite.swc library as a compilation dependency for the Flex project Replace all usages of mx.messaging.Consumer and mx.messaging.Producer by org.granite.gravity.Consumer and org.granite.gravity.Producer Each of these steps is quite easy, but to help understand what all this means, lets do it on an existing project. The easiest is to start from an example of the BlazeDS turnkey server that you can find here. As a first example, were going to migrate the Collaboration Dashboard sample project to Gravity. You should also download the latest distribution of GraniteDS here. First start the turnkey server database by executing blazeds-turnkey/sampledb/startdb.bat on Windows or startdb.sh on Linux/OSX, and the built-in Tomcat server by executing blazeds-turnkey/tomcat/bin/startup.bat or startup.sh. You should now have the turnkey server up and running and you can browse the url http://localhost:8400/samples. If you are a BlazeDS user, you most likely already know these examples. Migrating the Collaboration Dashboard Then import the project dashboard in Flash Builder by following the instructions that you will find at http://localhost:8400/samples/fb-project-setup.htm. Now to keep the BlazeDS samples working, make a copy of the tomcat/webapps/samples folder to tomcat/webapps/samplesgds. We can now follow the 5 steps described above :

1 de 6

17/09/2012 06:34 p.m.

Migrating from BlazeDS to GraniteDS | Granite Data Services

http://granitedataservices.com/migrating-from-blazeds-to-graniteds/

1. Remove all BlazeDS libraries from WEB-INF/lib (in fact remove all libs) and replace them by granite.jar (that you can find in the build folder of the GDS distribution) 2. Configure the Gravity servlet and listener for Tomcat in WEB-INF/web.xml : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <webapp> webapp> displayname>GraniteDS Samples</displayname> <displayname>GraniteDS Samples</displayname> <description>GraniteDS Sample Application</description> <! GraniteDS startup/shutdown listener > <listener> <listenerclass>org.granite.config.GraniteConfigListener</listenerclass> </listener> <! The Gravity messaging servlet for Tomcat > <servlet> <servletname>GravityServlet</servletname> <servletclass>org.granite.gravity.tomcat.GravityTomcatServlet</servletclass> <loadonstartup>1</loadonstartup> </servlet> <servletmapping> <servletname>GravityServlet</servletname> <urlpattern>/gravityamf/*</urlpattern> </servletmapping> <welcomefilelist> <welcomefile>index.html</welcomefile> </welcomefilelist> </welcomefilelist> </webapp> </webapp>

As you can see, its very similar to the declarations in BlazeDS, the only differences being the names of the implementations of the servlet/listeners and the fact that the servlet implementation itself depends on the target server. The reason is that it uses the specific CometProcessor API of Tomcat that allows asynchronous processing using Java NIO or the APR native library and is a lot more scalable than standard blocking servlets. 3. Configure the destination in WEB-INF/flex/services-config.xml: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <servicesconfig> <services> <service id="messagingservice" class="flex.messaging.services.MessagingService" messageTypes="flex.messaging.messages.AsyncMessage"> <adapters> id= <adapterdefinition id="default" class= class="org.granite.gravity.adapters.SimpleServiceAdapter" default="true"/> default="true"/> </adapters> </adapters> id="dashboard"> <destination id="dashboard"> channels> <channels> ref="mygravityamf"/> <channel ref="mygravityamf"/> </channels> </channels> </destination> destination> </ </service> </service> </services> services> </ <channels> channels> <channeldefinition id="mygravityamf" class="org.granite.gravity.channels.GravityChannel"> <endpoint uri="http://{server.name}:{server.port}/{context.root}/gravityamf/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channeldefinition> </channels> </servicesconfig>

As with web.xml, this is very similar to the BlazeDS services-config.xml or messaging-config.xml, but its simpler. The main differences are the implementation of the channel which is GravityChannel and the implementation of the default adapter SimpleAdapter. Also note that we have put everything in one single services-config.xml file because GraniteDS does not support file includes. This is not really an issue as the configuration of GraniteDS is generally very short. 4. Add granite.swc as a compilation dependency in Flash Builder (this swc can be found in the build folder of the GDS distribution), you should just have to copy the file in the libs folder of the project. It includes the specific implementations of Gravity messaging channels, consumer and producer. 5. Add the gds namespace xmlns:gds=org.granite.gravity.* in the <mx:Application> declaration and replace the usage of <mx:Producer> and <mx:Consumer> by <gds:Producer> and <gds:Consumer>. Last details, the GDS Consumer does not directly expose the message event in mxml, you will have to add consumer.addEventListener(MessageEvent.MESSAGE, messageHandler) just after consumer.subscribe(). 1 2 3 4 5 6 7 initApp():void private function initApp():void { consumer.subscribe(); consumer.addEventListener(MessageEvent.MESSAGE, messageHandler); } ... id="producer" destination="dashboard"/> <gds:Producer id="producer" destination="dashboard"/> <gds:Consumer id="consumer" destination="dashboard"/>

Now you can reconfigure the server for the Flex application by unchecking Use remote object access service in Flex Server. Also set the target folder to the turnkey server deployment folder :

2 de 6

17/09/2012 06:34 p.m.

Migrating from BlazeDS to GraniteDS | Granite Data Services

http://granitedataservices.com/migrating-from-blazeds-to-graniteds/

Finally restart Tomcat and browse http://localhost:8400/samplesgds/dashboard, you can check that the application works exactly the same. The main difference is that it now uses a lot less resources and can handle many thousands users instead of many hundreds. Migrating the Trader Desktop As a next example, we are going to migrate the Trader Desktop example. Fortunately most of the configuration has already been done for the previous example so we can skip steps 1 and 2. For step 3, we are simply going to add a new destination in services-config.xml for the data feed : 1 2 3 4 5 id="marketdatafeed"> <destination id="marketdatafeed"> channels> <channels> ref="mygravityamf"/> <channel ref="mygravityamf"/> </channels> </channels> </destination> </destination>

Note that we wont migrate the 3 different channel types present in the BlazeDS example (my-polling-amf, my-streaming-amf and per-client-qos-polling-amf) because the only channel type provided by GraniteDS is the long-polling Gravity channel which can advantageously replace all of the 3 others. Then follow steps 4 and 5. Note that the property subtopic of the mx:Consumer is named topic on the Gravity Consumer. Here is the part we have to change : 1 2 3 4 5 6 7 8 9 private function subscribe(symbol:String):void { subscribe(symbol:String):void var consumer:Consumer = new Consumer(); consumer.destination = "marketdatafeed"; consumer.topic = symbol; consumer.channelSet = new ChannelSet([channels.selectedItem]); consumer.addEventListener(MessageEvent.MESSAGE, messageHandler); consumer.subscribe(); consumers[symbol] = consumer; }

Were close to having finished, but note that this example uses the MessageBroker API to send messages from the server. We have to update this server thread to use the Gravity API. To do the changes quickly, we are simply going to create a new Java project (for example named samplesgds or whatever name you like) in Eclipse and use the path blazeds-turnkey-4.0.0.14931\tomcat\webapps\samplesgds as location for the project, so it will find the existing sources and compile them directly in WEB-INF/classes. Once you do this, there will probably we some compilation errors that are normal because we removed the BlazeDS libs and the existing samples expect these libs, so for now you may just delete the classes that do not compile. We just need the classes in the package flex.samples.marketdata for this example. The feed provider is the simple class flex.samples.marketdata.Feed. It you look at the source, it uses MessageBroker.getMessageBroker(null) to retrieve the current BlazeDS message broker. Its a bit different in GraniteDS because the object Gravity which is the equivalent of MessageBroker is not stored as a static instance but in the servlet context. So we have to pass it from the startfeed.jsp and stopfeed.jsp which can easily access the servlet context. Here are the modified Feed which the changes highlighted in blue : 1 2 public class Feed {

3 de 6

17/09/2012 06:34 p.m.

Migrating from BlazeDS to GraniteDS | Granite Data Services

http://granitedataservices.com/migrating-from-blazeds-to-graniteds/

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

private static FeedThread thread; private final Gravity gravity; public Feed(Gravity gravity) { this.gravity = gravity; } public void start() { if (thread == null) { thread = new FeedThread(gravity); thread.start(); } } public void stop() { false; thread.running = false; null; thread = null; } public static class FeedThread extends Thread { private Gravity gravity; public FeedThread(Gravity gravity) { this.gravity this.gravity = gravity; } true; public boolean running = true; private Random random; public void run() { Portfolio portfolio = new Portfolio(); List stocks = portfolio.getStocks(); int size = stocks.size(); int index = 0; random = new Random(); Stock stock; while (running) { stock = (Stock) stocks.get(index); simulateChange(stock); index++; if (index &gt;= size) { index = 0; } AsyncMessage msg = new AsyncMessage(); msg.setDestination("marketdatafeed"); msg.setDestination("marketdatafeed"); msg.setHeader(AsyncMessage.SUBTOPIC_HEADER, stock.getSymbol()); msg.setTimestamp(System.currentTimeMillis()); msg.setBody(stock); gravity.publishMessage(msg); try { Thread.sleep(20); Thread.sleep(20); } catch (InterruptedException e) { } } } private void simulateChange(Stock stock) { ... } } }

Then the changes in the jsps : 1 2 3 4 5 6 7 8 9 10 11 <%@page <%@page <% try import="flex.samples.marketdata.Feed"%> import="org.granite.gravity.*" %>

{ Feed feed = new Feed(GravityManager.getGravity(application)); feed.start(); out.println("Feed Started"); } catch (Exception e) { out.println("A problem occured while starting the feed: "+e.getMessage()); }

%>

You can see that the API is once again very similar to BlazeDS with only the slight change of using ServletContext. Note that when using the Spring integration for example, the Gravity object is a managed bean and can be directly injected in any Spring bean without needing to directly access the ServletContext. Now restart Tomcat and you should be able to start/stop the data feed and to access the example at http://localhost:8400/samplesgds/traderdesktop

4 de 6

17/09/2012 06:34 p.m.

Migrating from BlazeDS to GraniteDS | Granite Data Services

http://granitedataservices.com/migrating-from-blazeds-to-graniteds/

/traderdesktop.html.

Using Remoting
The BlazeDS turnkey does not include any advanced example using Hibernate or similar so we cannot easily demonstrate how to migrate this kind of applications. However we can simply show how to migrate a simple application using remoting, the Inventory example. Switching from BlazeDS remoting to GraniteDS remoting is by far the simplest of the 3 examples we wanted to demonstrate as there is stricly no change required in the source code, neither Flex nor Java. What we have to do is simply add the remoting filter and servlet in web.xml (provided you have already followed the previous examples) : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <filter> filter> filtername>AMFMessageFilter</filtername> <filtername>AMFMessageFilter</filtername> filterclass>org.granite.messaging.webapp.AMFMessageFilter</filterclass> <filterclass>org.granite.messaging.webapp.AMFMessageFilter</filterclass> </filter> </filter> filtermapping> <filtermapping> <filtername>AMFMessageFilter</filtername> <urlpattern>/graniteamf/*</urlpattern> </filtermapping> <servlet> <servletname>AMFMessageServlet</servletname> <servletclass>org.granite.messaging.webapp.AMFMessageServlet</servletclass> <loadonstartup>1</loadonstartup> </servlet> <servletmapping> <servletname>AMFMessageServlet</servletname> <urlpattern>/graniteamf/*</urlpattern> </servletmapping>

and configure the remoting destination and channel in services-config.xml : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <service id="graniteservice" messageTypes="flex.messaging.messages.RemotingMessage"> <destination id="product"> <channels> <channel ref="mygraniteamf"/> </channels> <properties> <source>flex.samples.product.ProductService</source> </properties> </destination> </destination> </service> </service> channels> <channels> id="mygraniteamf"> <channeldefinition id="mygraniteamf"> uri= http://{server.name}:{server.port}/{context.root}/graniteamf/amf"/> <endpoint uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"/> </channeldefinition> </channeldefinition> </channels> </channels>

Thats all, the example should work exactly the same with just this configuration change. Once you are here, you can then try the other features or GraniteDS such as automatic destination scanning which avoids the need to define destinations manually in the XML configuration, or externalizers which make possible to properly serialize Java enum, BigInteger and others.

Conclusion
If you are used to RemoteObject and Consumer/Producer, you should be able to use GraniteDS in no time, and benefit from more advanced features incrementally. In a future document, we will try to demonstrate how to migrate a more complex BlazeDS/Spring/Hibernate application to GraniteDS. If you have an idea of an existing project (with public source code) that could be used as a starting point for the article, dont hesitate to give us your suggestions.

What is GraniteDS GraniteDS is a comprehensive development and integration solution for building Flex / JavaEE RIA applications. The entire framework is open-source and released under the LGPL v2 license. Granite Data Services provides an optimized, QA-tested, pre-packaged platform of GraniteDS for mission critical applications as well as developer support and consulting.

Recent Posts Granite Data Services 2.3.2 GA Released Flex, GraniteDS and the Future of RIA GraniteDS Data Management Tutorial Quick start with GraniteDS

Recent Tweets amfPHP & GraniteDS: http://t.co/de3sad1d. Stay tuned! 12:53:31 PM August 23, 2012 from web ReplyRetweetFavorite Good to know, Adobe just patched a severe vulnerability in BlazeDS/LCDS http://t.co /mSZPU5zj. This was fixed in GraniteDS exactly 1 year ago 04:46:14 PM June 13, 2012 from web ReplyRetweetFavorite
Follow @graniteds 154 followers

5 de 6

17/09/2012 06:34 p.m.

Migrating from BlazeDS to GraniteDS | Granite Data Services

http://granitedataservices.com/migrating-from-blazeds-to-graniteds/

Copyright 2011 Granite Data Services Inc.

Terms of use - Privacy

6 de 6

17/09/2012 06:34 p.m.

You might also like