The Rational Developer

GraniteDS - Flex 2+/EJB3/Seam/Spring/Guice/Pojo

October 29, 2008 6:09 am

Reposted from The Serverside

GraniteDS, aims to deal with removing the complexities of creating an RIA Flex or AIR application. There are a lot of choices out there today for creating rich internet applications, each with its own set of advantages. When making the decision on which path to take, you want to get started easily but without sacrificing the ability to create a robust, scalable application. GraniteDS maintains this balance.

Some of the main features GraniteDS 1.1.0 GA offers:

Granite Eclipse Builder : A new Eclipse builder plug-in runs automatically Gas3 (the GDS ActionScript3 generator) each time you have created or modified a Java bean (likely an entity bean). When configured for your Java project via its graphical wizard or options panel, it replicates on the fly your entire Java model to its ActionScript3 mirror. Generated beans implement all required logic for strong typing externalization, lazy-loading support and Tide integration.
MXML/AS3 Web Compiler: it has the same features offered by its Adobe equivalent (on-the-fly compilation of MXML files deployed in your war) but also brings the ability to compile code from any input stream (from a simple String or a database for example). This has been contributed by Sébastien Deleuze (author of the Igenko project) and you may test it online here.

Tide is intended to be a full alternative for the Cairngorm + Flex Data Management Service stack. On Flex side, we have found Cairngorm to be a good Flex development framework but somehow tedious to follow (numerous files required for rather simple operations). On Java side, Flex Data Management is only available in LiveCycle Data Services and some features required for us aren’t implemented at all or not the way we expect them. Tide addresses all those requirements and targets for now the JBoss/Seam framework (Spring and plain EJB3 will come soon).

More Tide advantages:

• The client works with strongly typed Hibernate/JPA detached objects, not object proxies, thanks to GDS’ support of lazy initialized entities and the gas3 generator
• All client/server interactions are done exclusively by method calls on services exposed by the server, and thus respect transaction boundaries, security, and validation rules defined by the remote services
• All managed entity instances are unique in a Tide context. This allows you to maintain correct data bindings between calls to remote services.
• Collection paging and transparent initialization of lazy collections
• client-side entity caching
• Integration with hibernate validator
• Integration with Seam’s paged Query components which can be used as data providers for Flex UI components
• Integration with Seam’s events, both synchronous and asynchronous, allowing Flex client to observe events raised by the server
• Integration with Seam’s paged query component
• Support for Seam contexts (conversation, session, application, etc…)
• Increased exception handling support
• Simplified Configuration support. One services-config file can service all of your needs
• Lightweight component based Flex framework that is deeply integrated with the other features and can advantageously replace Cairngorm or PureMVC

An example call to a seam component would look like this:

public class HelloWorld {

public function helloWorld():void {
(1) var tideContext:Context = Seam.getInstance().getSeamContext();
(2) tideContext.helloWorld.sayHello(”Jimi”, helloResult);
}

private function helloResult(event:TideResultEvent):void {
(3) Alert.show(event.result);
}
}

You can also get some more information from the GraniteDs website.

Interview with GDS Founder Franck Wolff

October 21, 2008 5:44 pm

Franck took some time out of his busy schedule and gave a great interview with InfoQ. In it he gives comparison with GDS(Granite Data Services) BlazeDS and LiveCycle. Check it out here

Transparent Lazy Loading with Flex, Seam and GraniteDS

August 21, 2008 8:37 am


LazyLoading or LazyIntialization is one of those things that is not very sexy but provides tremendous amounts of scalability to your application. Being able to defer the loading of a collection to a later time if needed is some thing that I really like using.

 

Transparent Lazy loading can now be achieved easily.  With the new release of Tide RC 1.4 the ability to set up a collection have it loaded lazy and access it and display it from a Flex client with out any additional work! This will work with either JPA or Hibernate.

 

Tide is trying to make the whole process of lazy loading very simple in a flex client.

 

Currently Tide and Lazy Loading is only supported through the use of Seam. Later versions should add support for other frameworks as well.

 

Uninitialized collections are retrieved in from the server wrapped by a particular collection, which you can then use as a data provider for a grid.

 

With Tide it is preferred that you allow Seam to manage the EntityManager.

 

i.e.

 

<persistence:entity-manager-factory name="ejb3" persistence-unit-name="ejb3"/>
 
<persistence:managed-persistence-context name="entityManager" entity-manager-factory="#{ejb3}"/>

 

This allows Tide to easily find the EntityManager server up your data.

 

Also you will want to name your entities because this will allow Seam to manage them and allow Tide to do a look up on it.

 

@Name("order")
@Entity
public class Order {
 ...
}

 

 

If you are dealing with multiple PersistenceContexts or HIbernateSession  in your application then retrieval of entities should happen through a conversation For example if you retrieve your orders through an established seam component

 

  @Begin
   public Order getOrder(Long orderId) {
        Query ejbQuery = entityManager.createQuery(”from Orders where id = :orderId”);
       ejbQuery.setParameter(”orderId”, orderId);
       Order o = ejbQuery.getSingleResult();
 
        return o;
   }
 
   @End
   public void processOrder(Order order) {
     
   }

 

You will also need to use the GasGenerator to generate your actionscript objects for you with the proper tide extensions. There is plug in(Eclipse) that has just been released that makes it easy to generate your action script objects easily.

 

That’s it Tide takes care of the rest! If you want to see an example of lazyloading in use take a look at the graniteds-seam project

Granite 1.1 RC3 Released

July 23, 2008 9:21 am

Granite 1.1 RC3 has been released, this has been reproduced from here

Granite Data Services 1.1.0 Release Candidate 3 is out. You may download it, as usual, on Sourceforge here.

This new release is actually a true release candidate since we have now reached a real feature freeze… Beside several bugfixes, this release comes with a huge Tide improvement and (again) an almost complete rewrite of gas3.

Tide specific new features (more informations will be soon available in GDS blog):

  1. Full support of Seam events (both synchronously and asynchronously) via Gravity (data pushing).
  2. Deeper integration with the Seam Query component and support for paged collections (you may bind a Seam Query to a DataGrid that will load collection items on demand).
  3. Transparent initialization of lazy loaded collections.

Gas3 refactoring:

  1. I had to rewrite again Gas3 in order to make easier the development of an Eclipse Builder (not yet available) and future extensions (different kind of inputs, such as some configuration XML files, in order to generate ActionScript3 code). The GDS Eclipse builder will mainly give automatic as3 generation features: when a Java class, in the scope of the generator, is created/modified/(re)moved, the builder will update automatically and accordingly as3 classes.
  2. There is no changes for the average user but, if you have written a custom “controller”, you should now write a custom “transformer”…

Here is the complete release note for this RC2 (see also GDS Jira):

New Features

  • [GDS-117] - Tide: as3 client exception handlers
  • [GDS-119] - Tide: Management of Seam events synchronous & asynchronous with Gravity
  • [GDS-120] - Tide: Deeper integration with Seam Query framework component and support for paged collections
  • [GDS-139] - Tide: implement automatic lazy loading of collections

Improvements

  • [GDS-125] - tide.seam.Context expects type Seam in constructor, which is not necessary
  • [GDS-135] - Integrate Tide managed entities with LCDS [Managed] annotation to simplify the gas3 templates
  • [GDS-137] - Tide: implement merging of maps in Context
  • [GDS-138] - Refactor Gas3 for Granite Eclipse Builder and future extendability
  • [GDS-140] - Tide: Filtering of target components

Tasks

  • [GDS-115] - Use mx.logging instead of trace in all as3 components

Bugfixes

  • [GDS-116] - Tide: Incorrect destruction of finished conversation contexts
  • [GDS-118] - Tide: NaN numbers incorrectly managed in context merge
  • [GDS-122] - Authentication doesn’t work with Gravity
  • [GDS-124] - Typo in bean.gsp (interfaceProperties instead of interfacesProperties)
  • [GDS-126] - Tide: Merge of collections in context loses order
  • [GDS-127] - Improved saving of entity values before sending to server
  • [GDS-128] - Tide: request wrapper not correctly cleaned during consecutive messages in the same http request
  • [GDS-129] - Tide: Asynchronous impl depends on deprecated Seam 2.0.0 API
  • [GDS-130] - Tide: remove messages dependency on JSF FacesContext/Locale
  • [GDS-131] - Tide: missing update of id for new entities
  • [GDS-132] - Error when deserializing RemotingMessage
  • [GDS-133] - DefaultMethodMatcher does not find some methods with complex generic types
  • [GDS-134] - Stateful session beans are cached in application context (should be in session cache)
  • [GDS-136] - Incorrect management of context variables in conversation scope

Conversations and Flex what are they good for?

July 3, 2008 10:53 am


Hi everyone! I have been a bad blogger and haven’t updated my site in a while. I have no excuse other than I have been extremely busy at work. As I was thinking what would I write about the thought occurred to me why is it that conversations are important to a Flex application?  One of the things that I thought Adobe left out was some sort of state management in a Flex application.

 

I come from a client server background. State management has always been one of those things that started out easy but as the application grew became very nasty.  I would run in to memory leaks and unknown errors after the application would run for a long time. Flex essentially gives us the power of a desktop application with the deployment model of the web. Unfortunately the problems of memory leaks have not been resolved. Check out this helpful post.

 

One of the things I think Adobe left out was a way to manage state on the client. Flex provides a garbage collector and Flex Builder has a profiler. These tools will help you when things have gone wrong however they really don’t help you when it comes to how you do state management. You can store the state in the main form and pull it out and replace the vars you have stored there. This can become a repetitive and error prone process. To me this is very similar to the error prone process that Seam solved with conversations and use of the HttpSession for state management. It is also incorrect to think because you have a garbage collector you won’t have any memory leaks.  Seam and Tide can help with the problems associated with state management.

 

Tide will keep the state on the client synchronized with the state on the server. Starting a conversation there will get propagated to the client giving you a new context that is specific to that conversation. This will help a lot with transient data or more specifically data that is changing quite a bit.

 

 

Lets take a look at the HotelBookingAction which initiaties a conversation

 

  @Begin

   public void selectHotel(Hotel selectedHotel)

   {

      hotel = em.merge(selectedHotel);

   }

  

 

 

  The Tide code would look something like this

 

tideContext.hotelBooking.selectHotel(hotel, selectHotelResult);

 

private function selectHotelResult(event:TideResultEvent):void

 

event.context à this is the context that stores the conversation scoped vars.

 

Once you have the context for the conversation, all of the vars that are specific to that conversation are available. When that conversation ends and on the next server invocation Tide will remove this context (available in RC3) from memory, essentially destroying it. This will give you the power to control state management with Seam. So with Seam and Tide you can easily maintain state and avoid memory leaks.

 

With Tide’s ability to manage state on both sides, you end up with a transparent state mechanism. This helps a lot with what I term as transient data. In other words if you have a complex application with data that is moving in and out quite a bit, a conversation might be a good place for this. You don’t have to worry about making sure that the object is stored in the main form of the application so it will reside in memory. Seam and Tide can take care of that for you. You can concentrate on the business logic. Make sure the conversation has started and stopped and even start another one. This can especially be important with applications that are running for long periods of time.

Uncloaking ‘invisible’ Flash Web content

July 2, 2008 8:35 am

Check this link out. Adobe is providing Google and Yahoo with optimized flash player technology so that there spiders can index them as well!

GraniteDS 1.1.0 RC2 Released!

June 13, 2008 1:03 pm

GraniteDS 1.1.0 RC2 has been released it includes several improvements and bug fixes. One of the more exiting new features is a Servlet basexd MXML/AS3 compiler! Head over to GraniteDS and check it out.

GraniteDS 1.1.0 RC1 and Tide Released!

April 30, 2008 11:27 am

You can see the laundry list of what is included in it here. I think one of the biggest features that is included in it is Tide.

. I am going to borrow from the Tide quick presentation, which you can find here. This new subproject (Tide) is aimed at improving the data services part of GraniteDS and simplify the Flex client programming model when integrating with server side frameworks. With Tide you can code your back ends normally.There isn’t any code that has to be added specifically for Flex or Tide.

One of the great things about using Seam and Tide (Flex) together is it really simplifies your development efforts. The same web.xml, service-config.xml and granite-config.xml can be used across all of your projects and don’t require any modifications. In other words you don’t have to constantly add entries to the service-config.xml! As of this moment we are using it with Seam-2.0.0 GA and have not tested it with the other releases. To find out how to set up your project refer to the Readme.txt file in the helloworld-tide project. You can download the project for this code here , this project also includes a readme.txt file with instructions on how to set up a new project.

Some high points Tide includes

Using existing Seam components

Integration with Seam bijection

Propagation of context messages from the server

Integration with Seam security, in particular the identity component

Integration with server side validation (Hibernate Validator)

For a more advanced project you can download graniteds-seam-booking

Let’s look at a hello world example:

Seam:

package com.rationaldeveloper.action;

import org.jboss.seam.annotations.Name;

@Name(”helloAction”)

public class HelloAction {

public String sayHello(String name) {

return “Hello ” + name;

}

}

Flex :

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”>

<mx:Script>

<![CDATA[

import mx.controls.Alert;

import org.granite.tide.events.TideResultEvent;

import org.granite.tide.seam.Seam;

import org.granite.tide.seam.Context;

private function sayHello(): void {

var ctx: Context = Seam.getInstance().getSeamContext();

ctx.helloAction.sayHello(txtName.text,sayHelloResult);

}

private function sayHelloResult(result: TideResultEvent): void {

Alert.show(String(result.result));

}

]]>

</mx:Script>

<mx:Button x=”46″ y=”78″ label=”Say Hello” click=”sayHello();”/>

<mx:TextInput x=”132″ y=”78″ id=”txtName”/>

</mx:Application>

Seam 2.0.2.CR1 released!

April 9, 2008 5:28 am

Admittedly most people reading this are probably aware already but if you aren’t head over to seamframework and check it out. There are a lot of bug fixes and enhancements.

GraniteDS Tide subproject

April 7, 2008 1:35 pm

Contributed from (William Drai and Franck Wolf)
We are in the process of releasing the GraniteDS Tide subproject as part of GraniteDS 1.1.
This new subproject of GraniteDS will improve the Data part of GraniteDS and simplify the Flex client programming model when integrating with server side frameworks.

Tide has been designed after our first attempts to develop Flex+Seam projects, with one main idea in mind: remove all the useless and redundant declarations and integration code both on Flex side and on Seam side (for example the dozens of destinations for RemoteObjects in service-config.xml).

Note that this is still an alpha. The code and some examples will be available shortly.

In a first step we are focusing on a strong integration with Seam and Hibernate, built on the existing Granite/Seam integration to make the use of remoting really easy. The important point is that Tide+Seam allows the use of existing Seam components without having to rely on any particular service facade or adapter.

Tide is heavily based on the concept of a client context, which proxies all communications between the client and the server. This client context provides an entity cache and a component container, similar to the server PersistenceContext and Seam context.
Let’s start by a small example with the Seam helloWorld component :

Seam component :
@Stateless
@Name(”helloAction”)
public class HelloAction implements HelloLocal {
public String sayHello(String name) {
return “Hello, ” + name;
}
}

Flex code :
public function init():void {
Context seamContext = Seam.getInstance().getSeamContext();
seamContext.helloAction.sayHello(”Jimi”, resultHandler); // Triggers the remote call of the ‘helloAction’ component
}

private function resultHandler(event:TideResultEvent):void {
trace(event.result); // Should output ‘Hello, Jimi’…
}

This is very similar to the JavaScript Seam remoting way of calling server components. The Context object proxies all calls on its managed components and transmits them to the server through a single hidden RemoteObject. That means that just one RemoteObject has to be declared in services-config.xml. A faultHandler can optionally be specified for handling errors.

Let’s go one step further with an extract of the Seam contactlist example :

Seam components :
<fwk:entity-query name=”contacts” max-results=”5″>
<fwk:ejbql>from Contact</fwk:ejbql>
<fwk:order>lastName</fwk:order>
<fwk:restrictions>
<value>lower(firstName) like lower( concat( #{exampleContact.firstName}, ‘%’ ) )</value>
<value>lower(lastName) like lower( concat( #{exampleContact.lastName}, ‘%’ ) )</value>
</fwk:restrictions>
</fwk:entity-query>

<component name=”exampleContact” class=”org.jboss.seam.example.contactlist.Contact”/>

Flex code :
public function init():void {
Context seamContext = Seam.getInstance().getSeamContext();
seamContext.exampleContact.firstName = ”;
seamContext.exampleContact.lastName = ‘hendrix’;
seamContext.contacts.getResultList(resultHandler); // Triggers the remote call of the ‘contacts’ component.
}

private function resultHandler(event:TideResultEvent):void {
var list:ArrayCollection = ArrayCollection(event.result);
}

Here the main point is that the exampleContact has been sent to the server along with the remote call of getResultList. As the Context is an ActionScript proxy, it is able to detect all assignments on objects attached to it and to propagate them when needed.
Again the important thing is that we have been able to use the Seam framework component as is.

Another kind of use is also possible and makes binding of server objects in mxml very easy :

MXML code :
<mx:TextInput id=”inputFirstName”/>
<mx:TextInput id=”inputLastName”/>
<mx:Button label=”Go” click=”seamContext.exampleContact.firstName = inputFirstName.text; seamContext.examplePerson.lastName = inputLastName.text; seamContext.contacts.refresh();”/>

<mx:DataGrid id=”contacts” dataProvider=”{seamContext.contacts.resultList}”>

</mx:DataGrid>

The resultList collection will be updated each time the refresh() method is called on the remote component. Interestingly, the collection instance itself is not replaced, instead data received from the server are merged with the existing data, and even the instances of Contact are kept and merged when possible, allowing the DataGrid to correctly keep its selectedItem (this would not be the case if the object instances were overwritten).

Lastly, Tide integrates with the Seam component bijection and all outjected objects and datamodels are propagated from the server to the client context.
Here is an example from Seam booking :

Seam component :
@Stateful
@Name(”hotelSearch”)
@Scope(ScopeType.SESSION)
@Restrict(”#{identity.loggedIn}”)
public class HotelSearchingAction implements HotelSearching {

@PersistenceContext
private EntityManager em;

private String searchString;

@DataModel
private List<Hotel> hotels;

public void find() {
page = 0;
queryHotels();
}

public void nextPage() {
page++;
queryHotels();
}

public String getSearchString() {
return searchString;
}

public void setSearchString(String searchString) {
this.searchString = searchString;
}

}

MXML code :
<mx:TextInput id=”inputSearchString”/>
<mx:Button label=”Search” click=”seamContext.hotelSearch.searchString = inputSearchString.text; seamContext.hotelSearch.find();”/>

<mx:DataGrid id=”hotels” dataProvider=”{seamContext.hotels}”>

</mx:DataGrid>

The project is still alpha and can only be built from the subversion trunk for the moment, but we expect to get a preview version in the forthcoming GraniteDS 1.1 RC and a stable version as part of the final release of GraniteDS 1.1.

We hope that it will greatly simplify the development for people currently working with both Flex and Seam.

Don’t hesitate to try it and give some feedback.