So what's in this first implementation :
Note that for now it will work only with the Weld implementation, as conversation support requires using some non public JSR-299 API.
Also the supported containers are for now JBoss 5.2 trunk (available here and GlassFish V3 starting from build 70 (available here). It will probably not work in Tomcat for now.
The GraniteDS distribution contains a graniteds-tide-jcdi example that can be deployed in any of these application servers.
Configuration
The configuration is almost the same as for other server framework integrations and consists in five parts :<granite-config scan="true">
<security type="org.granite.messaging.service.security.TomcatSecurityService"/>
<tide-components>
<tide-component instance-of="org.granite.tide.jcdi.JCDIIdentity"/>
<tide-component annotated-with="org.granite.messaging.service.annotations.RemoteDestination"/>
</tide-components>
</granite-config>
<factories>
<factory id="tideJcdiFactory" class="org.granite.tide.jcdi.JCDIServiceFactory"/>
</factories>
Remoting
Once this is done, add your named JCDI bean and annotate it with @RemoteDestination :
@Named("helloWorld")
@RemoteDestination(id="helloWorld")
public class HelloWorld {
public String hello(String name) {
return "hello" + name;
}
}
Then you can easily call it from Flex using Tide remoting and injection :
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
preinitialize="Jcdi.getInstance().initApplication()">
<mx:Script>
<![CDATA[
import org.granite.tide.jcdi.Jcdi;
import org.granite.tide.Component;
[In]
public var helloWorld:Component;
]]>
</mx:Script>
<mx:Button label="Hello" click="helloWorld.hello('Barack')"/>
</mx:Application>
You can even use typesafe client proxies (e.g. public var helloWorld:HelloWorld) if you have generated them with gas3. Maybe in RC2 we'll try to use completely typesafe service invocation and will not require @Named beans any more.
Events
Support for events is relatively similar to what exists for Seam, but with JCDI it uses typesafe events.Define your Java and as3 event classes (in the final release it will be possible to generate the as3 event class automatically with gas3) :
public class GreetingEvent {
private String name;
public GreetingEvent(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
[RemoteClass(alias="test.app.GreetingEvent")]
public class GreetingEvent extends AbtractTideEvent {
public var name:String;
}
Fire an event from the server method :
@Named("helloWorld")
@RemoteDestination(id="helloWorld")
public class HelloWorld {
@Inject @Any
EventgreetingEvent;
public String hello(String name) {
greetingEvent.fire(new GreetingEvent(name));
return "hello" + name;
}
}
Then just declare a remote observer in the Flex application and it will be triggered whenever the event is dispatched during a remote call initiated from Flex.
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
preinitialize="Jcdi.getInstance().initApplication()">
<mx:Script>
<![CDATA[
import org.granite.tide.jcdi.Jcdi;
import org.granite.tide.Component;
[In]
public var helloWorld:Component;
[Observer(remote="true")]
public function greet(event:GreetingEvent):void {
trace("Greeting to " + event.name);
}
]]>
</mx:Script>
<mx:Button label="Hello" click="helloWorld.hello('Barack')"/>
</mx:Application>
This is really just an early implementation of this integration and it will be updated for the final release of the JCDI specification and RI.
Our feeling is that JCDI is a perfect fit for Flex RIAs with an event-driven architecture. JCDI applications looks extremely clean and even JBoss Seam provides a lot more features, they do not necessarily make sense with a RIA front-end.
Feel free to give some feedback and maybe some ideas for this integration.
9 commentaires:
Looks good. The only think I wondered is do you really need to use a string based @Name to refer to the bean from the client side? Could you use type-based resolution instead?
http://in.relation.to/Bloggers/GraniteDSAndCDI
This is awesome! Nice work!
Hi Gavin, thanks for talking about this on your blog.
As I told in the post, type-based invocation will be implemented in the final release. It's in fact almost ready but requires many changes in the client-side framework so we had not enough time to include it in RC1.
This looks cool, we are looking to start migrating a largeish application (bit by bit) from Oracle Forms to a more modern platform and with the advent of Java EE 6, the pieces are slowly coming into place.
There are many nice AJAX based JSF components frameworks but some views could benefit from an alternative RIA frontend and this certainly looks like a candidate. We would of course like to minimize code duplication so the tighter the integration is, the better (entities in dropdowns, validation integration, exception propagation etc)...
Learning the GraniteDS and flex. Spent the whole weekend to build the jcdi example in eclipse. But fail.
Than, follow the instruction to build the jcdi example using ANT script. Deployed to Glassfish or JBoss 5.2.1 GA. Both are having the same exceptions:
SEVERE: Exception while pre processing the request message.
java.util.NoSuchElementException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:796)
at java.util.HashMap$KeyIterator.next(HashMap.java:828)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
at org.granite.jcdi.JCDIInterceptor.before(JCDIInterceptor.java:104)
at org.granite.messaging.amf.process.AMF3MessageProcessor.process(AMF3MessageProcessor.java:56)
at org.granite.messaging.amf.process.AMF0MessageProcessor.process(AMF0MessageProcessor.java:78)
at org.granite.messaging.webapp.AMFMessageServlet.doPost(AMFMessageServlet.java:59)
Any advise?
Keith
granite countertops edmonton
Thanks, you guys that is a great explanation. keep up the good work..
very informative your article. Thank you for sharing this post.
granite countertops services Toronto
Enregistrer un commentaire