wesleyhales.com

Runtime Type Detection and Usage with Weld

04 May 2011

Java | cdi | hornetq | infinispan | jms | jsf | richfaces | seam | weld |

About TweetStream


tweetstreamIn developing the TweetStream demo for the JBoss World keynote and JUDCon presentation, I wanted to use CDI in a way that would choose the implementation of a given type at runtime. With Qualifiers and Producers, CDI gives you the power to do this.
A little bit about the usecase: The TweetStream application is an app that Jay Balunas and I developed over the past few months for our presentation at JUDCon and JBoss World 2011. It was purposely developed with a myriad of JBoss community projects to showcase how you can build a mobile HTML5 web application (which runs on Android and iOS devices) with things like scalable data grid, JMS, JSF2, HTML5/CSS3 and other middleware technologies. This application (TweetStream) was also chosen to be part of the literally incredible JBoss World 2011 keynote.
So, we had 2 scenarios – 1) for our presentation we needed a mobile app that could run solely on it’s own so that users could pull the source code, see how we did things, and run it. 2) For the keynote, we had to make our app integrate with the Infinispan datagrid that was already setup as part of the keynote demo. The data stored on this grid utilized Drools and complex event processing as part of the keynote, so our app had to consume that data for that environment.
So we got our tweet data from the true source (twitter4j) during our JUDCon presentation, and then from the data grid during the keynote. We could have used CDI alternatives, but I wanted a true solution with no XML configuration and runtime detection.


The Code...


So we have 2 Qualifier Types:
@TwitterLocal for the JUDCon demo impl
@TwitterServer for the keynote impl

We used infinispan in both instances, but our @TwitterLocal is a single node caching a direct twitter stream from Twitter4J.

Now that we have our types defined as follows…

@Qualifier

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})

public @interface TwitterServer

{

}



@Qualifier

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})

public @interface TwitterLocal

{

}

We need not only an implementation of each, but also a deciding bean that tells us which type to use.

First, our implementation of each Type implements an interface:

public interface TwitterSource {

  public void init();

And our implementations have a different usage of the init method. TwitterLocal starts the stream coming from twitter and updates the infinispan cache. TwitterServer starts a method which allows us to start receiving data from the keynote which uses complex event processing and a datagrid with 6–8 nodes.

So now, how do we decide which Type to use? There are a few different ways to do it, but in the case of this being a demo and not a lot of time on my part. I used this approach:

public class TweetStream {



  @Inject

  @Any

  Instance<TwitterSource> twitterSource;



  class TwitterLocalQualifier extends AnnotationLiteral<TwitterLocal> implements TwitterLocal

  {

  }



  class TwitterServerQualifier extends AnnotationLiteral<TwitterServer> implements TwitterServer

  {

  }



  boolean initialCheck = true;

  boolean demoexists = false;



  @PostConstruct

  private void init()

  {

     getTwitterSource().init();

  }





  @Produces

  public TwitterSource getTwitterSource()

  {

     if (initialCheck)

     {

        try

        {

                   Class.forName("org.jboss.jbw2011.keynote.demo.model.TweetAggregate");

           log.info("Running in JBW2011 Demo Mode.");

           demoexists = true;

        }

        catch (ClassNotFoundException ex)

        {

           log.info("Running in local JUDCon2011 Demo Mode.");

        }

        initialCheck = false;

     }



     Annotation qualifier = demoexists ?

        new TwitterServerQualifier() : new TwitterLocalQualifier();

     return twitterSource.select(qualifier).get();

  }

This is all in the source code. Feel free to pull it and make improvements or run it to see it in action. There are many more blog posts to come from this demo, so stay tuned…

Contextual PortletMode changes using the JBoss Portlet Bridge

10 December 2009

Java | portal | portlets | seam |

By default, the JSR-301/329 portlet bridge manages your navigation history during PortletMode changes. Meaning that, if the user is clicking around in the portlet "view" mode and decides to click the help icon (help mode), the user should be directed to the place where he left off in help mode - and vice versa. Of course, if the user has never been in help mode during the current session, he will go to the default help viewId.

Why use portlet modes instead of javascript widgets?

First I would like to give you a little justification of the beauty of this feature. Some people will argue the point of "Why do you need different modes like, Help and Edit?", when you could add some cool "javascript of the week" that would dynamically display what you intended to present in one of the given modes. Well, you could develop your interactions either way but it really isn't a question of why. It's a question of "How?". How do you want users to interact with your applications? And since you have already made the decision to invest in a portal solution, why not use the features that are built in and that stay consistent across the entire UI? Any UI Developer or Interaction Designer will tell you that adding cool javascript widgets adds another layer of complexity and maintenance, thus adding to developer time and bottom line ROI. In addition, when you develop any servlet based application to work within a portal environment, you are properly separating your concerns when you use these modes (without even realizing it in most cases). You are presenting distinguished flows for different trains of thought and making it easier for users to accomplish the task at hand.

The Usecase

Ok, off the soap box and onto the use case. Let's say your user is filling out a beloved expense report. It's probably one of his top 5 things that he loves most about his job ;) Seriously, his IT department just launched a new intranet portal using the latest and greatest GateIn platform and they completely revamped their old Seam application that was used for expense report submissions to run as a portlet.

So, Joe User starts to fill out his expense report in a 6 step wizard. He gets through the first few steps and arrives at a screen asking for his cost center and other details that he has no idea about. Behold the beautiful question mark(help mode) in the top right hand corner of his portlet window! Joe clicks the button and sees exactly the information he needs, and he also sees a link at the bottom of the screen that says “add this to the form”. Joe clicks it, and is returned to his expense report with all of the details pre-populated in his form. Not only was the help screen easy to understand, but it was just a basic .xhtml page that can be templated and maintained by any UI developer without any special javascript kung fu.

The next screen (in view mode), asks him to itemize each receipt and expense. Since he took a trip to Euro-land, all of his receipts are in Euros. And since he recently just got his internet privileges suspended (and no, he won't tell us why) he has no idea what the current conversion rates are. Once again, Joe clicks the help button and is presented with a clickable table of currency options. Not only that, but the finance department has placed some important notifications on this page via CMS. Joe reads the notifications and clicks on "Euros" and is taken back to a modified input table that auto converts his itemized euro(€) values to USD($).

As you can see, these are just random examples of possibilities of detecting PortletMode changes with GateIn, Seam, and RichFaces. The real beauty of this code is detecting the actual mode change and providing contextual help. This is not currently provided by the bridge as a default behavior, so here is the code to do it:

The Code

First create a simple session bean with the following code. This will allow us to get a handle on the current mode.

private String mode; public String getMode() { Object responseObject = FacesContext.getCurrentInstance().getExternalContext().getRequest(); if (responseObject instanceof RenderRequest) {

RenderRequest renderRequest = (RenderRequest)responseObject; if(renderRequest.getPortletMode().toString().equals(mode)){ mode = null; }else{ mode = renderRequest.getPortletMode().toString(); }

} return mode; } public String getFromView() { PortletSession portletSession = (PortletSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false); String viewId = (String)portletSession.getAttribute("javax.portlet.faces.viewIdHistory.view");

viewId = viewId.substring(0,viewId.indexOf("?")); return viewId; } public void setMode(String mode) {

this.mode = mode; }

Next add something similar to this in pages.xml

 
 <page view-id="/expenseWizard/*" action="#{mode.getMode()}"> 
 <navigation> 
 <rule if-outcome="help" if="#{mode.getFromView() == '/expenseWizard/step3.xhtml'}"> 
 <render view-id="/helpPages/step3help.xhtml"/> 
 rule> 
 <rule if-outcome="help" if="#{mode.getFromView() == '/expenseWizard/step4.xhtml'}"> 
 <render view-id="/helpPages/step4help.xhtml"/> 
 rule> 
 navigation> 
 page> 
 

JBoss Portlet Bridge Beta2 Released!

11 April 2008

Java | bridge | portlet | richfaces | seam |

The JBoss implementation of the JSR-301 spec allows developers the ability to develop portlets with any mixture of Seam, RichFaces, and JSF. One of the main goals of the 301 specification is to make life easier on the JSF developer who chooses to integrate his web application into a portal environment. The JBoss Portlet Bridge project builds on that vision of no-hassle integration and setup.

Read more about what is included in this release.

JBoss Portlet Bridge project page.

JBoss Portlet Bridge with Seam support released

14 February 2008

Java | bridge | jsf | portlet | richfaces | seam |

It has been quite a while in the making (a couple months) and we finally have a beta release of the portlet bridge.

The JBoss Portlet Bridge is an implementation of the JSR-301 specification to support JSF within a portlet and with added enhancements to support other web frameworks. Currently the bridge supports any combination of JSF, Seam, and RichFaces to run inside a portlet.

See the project page for more details and a live demo.


XHTML to PDF with a Seam filter

17 December 2007

Java | pdf | seam |

After reading this article showing how to create a servlet filter that will render XHTML to a PDF, image, or SVG, I was inspired to try it out as a filter in Seam using the @Filter annotation. The filter installation went smoothly but getting Flying Saucer to parse the generated JSF and css background images was not so easy.

First off, generated markup from any given JSF component is not guaranteed to be good markup. So I had to make use of cyberneko html parser. The servlet filter parses the generated response and then neko cleans up any non standard xhtml elements.

One huge css tip is make sure you declare media="print" or media="screen,print" on your xhmtl css reference. Naturally it would be good to split the 2 style sheets but laziness forced me to use one for both.

An Example Application

A few months ago, I wrote a simple website for the neighborhood I live in using Seam. I tried to start out writing this site using Ruby on Rails but I just wasn't impressed compared to what Seam offers. (Even for a small one-off website)

So below are 2 live links that show the code in action and parsing a real world example. Enjoy...


The Code

It's pretty cool not having to define a servlet filter in your web.xml. Just add the @Filter annotation to the top of the class and wala. I had to add the within="org.jboss.seam.web.ajax4jsfFilter" attribute to the annotation so FS could render the RichFaces images/resources.

Writing a FaceBook app

03 December 2007

Java | facebook | seam |

I just recently setup a Facebook profile in an effort to network with other like minded professionals and because I haven't really had a reason to do so until I joined JBoss. It is astonishing how many people have accounts and are using Facebook on a daily basis. I really haven't followed the social networking fad/trend that has been going on for the past few years and I keep wondering what is going to be next. Linking people to each other in some way, shape, or form based on interests, work , hobbies, etc. has been going since modern civilization began and the social internet is just one of the many channels to do it.

Now with the advent of Open Social I'm thinking that broadcasting to all of the different social networks is kind of riding the coat-tails of the fad, but is sure to bring out some interesting mutations in the social scene.

Open Social is supporting quite a few different scenes (Engage.com, Friendster, hi5, Hyves, imeem, LinkedIn, MySpace, Ning, Oracle, orkut, Plaxo, Salesforce.com, Six Apart, Tianji, Viadeo, and XING) but not FaceBook. I wonder why this is?

This is interesting stuff, but like I said, what is to come after "Social"? The basic concept won't change, people will always want to hook up and network. Anyway, the whole point of this article is just to explain how and why I wrote a FaceBook application.

iProject

As I browsed through the available apps on Facebook, there were few that actually did anything useful for the professional minded. There are some that let you manage contacts and business card type things, but nothing that really stood out. All I wanted to do is extend the built in Group application so that I could put a summary of my group or project on my profile page, but also add links to things that pertain to the product or service my project represents along with other custom features that a professional group would want.

This led me to the iProject application(I'm still trying to think of a better name). It basically uses the Facebook api to gather information on a group, then it let's you extend the group by adding members, blog feeds, etc. It currently supports Jroller, Blogger(atom/feedburner), and Wordpress blogs. It "will" also be capable of adding members as "core members" of the project along with other features.

So basically, if you are a member of an existing group on Facebook, you can extend it and make it better on your profile page. You can preview the beta on my profile

I used Seam and the Facebook java api along with commons httpclient to get the blog feeds. For the ui, I had to use a provided FBML (facebook markup language) dtd that's buried on Facebook's wiki so that I could use Facelets for the view. It was easy for me to use Seam just because I'm so used to getting things done quickly with it. Furthermore, these types of extensions to the framework could bring in some interesting new advantages.

Seam 2.0GA in JBoss Portal (in 5 minutes)

15 November 2007

Java | jboss | portal | richfaces | seam |

**Update - See this article for more info.

Running Seam 2.0 on Tomcat(EJB3) using Maven and Cargo

12 October 2007

Java | cargo | maven | seam | tomcat |

In this article I review a simple Seam 2.0.0.CR2 app that deploys to Tomcat 6.0.13 with JBoss Embedded Beta2.

It's great to see Seam move to Maven because tracking and installing all those dependencies in a local repository was a pain in the ass! This project is moving fast, and if you wanted to keep up with the latest version, it was a lot of work. So now that my life is easier, I thought I would make the Seam+EJB+Tomcat user's life a little easier also.

The following is included in this sample app:

  • Trinidad 1.0.2
  • JBoss RichFaces
  • JAAS
  • Drools
  • JBPM
  • And everything else that seam and Embedded/EJB3 provides out of box.

All you need to have is Maven 2.0.x installed. The rest is cake. During the installation Cargo will download a zip file from the JBoss Maven repository. This is the Tomcat 6.0.13 distro with Embedded already installed and setup. Nothing else has been added to it.

Directions

  1. Checkout the project and getting started directions Here

*Note - I used a stub for the datasource in TOMCAT_HOME/lib/deploy. Don't forget that this deploy directory is supposed to be the same as JBoss AS deploy directory.

I used a few cool things in the maven pom setup:

  • It seems you can trick cargo into using the latest version of tomcat. The documentation says Tomcat5x is only supported for the container, but I didn't have any problems using 6.0.x with the Tomcat5x containerId
  • The cargo.container.url can be local, there is an example in the web/pom.xml (at the bottom)...So once you have this downloaded in you target dir, I would copy it somewhere outside of target and change the cargo.container.url to point to it. It will save time from downloading and bandwidth. It would be cool to add it as a dependency and then unzip from your local maven repo, but I haven't tried it yet.
  • Like I mentioned earlier, if you want to disable auto start of the Tomcat server you should disable this section of the cargo plugin in web/pom.xml
     
     <executions> 
     <execution> 
     <id>start</id> 
     <phase>install</phase> 
    
     <goals> 
     <goal>start</goal> 
     </goals> 
     </execution> 
    
     <execution> 
     <id>deploy-app</id> 
     <phase>install</phase> 
     <goals> 
    
     <goal>deployer-deploy</goal> 
     </goals> 
     </execution> 
     </executions> 
     
    
  • I have another version of this sample app that uses profiles to build either an EAR for JBoss or a WAR for Tomcat+Embedded. Michael Yuan recently touched on this subject about the EAR+Seam maven impl and did a great job breaking it down. I will try to post the sample app that lets you build a war for Tomcat or an EAR for JBoss all based on the maven profile i.e... mvn install -Ptomcat or mvn install -Pjboss This is the power of Maven2 and there is soo much more you can do with it.

btw, I haven't blogged since I've become an employee for JBoss, a division of Red Hat. I'm working on the JBoss Portal Team and I must say that the company is awesome, my team is awesome, and everyone I have met and talked to have been, you guessed it, AWESOME!

My first Seam 2.0 app

01 August 2007

Java | flying | hibernate | jsf | saucer | seam | trinidad |

Before I begin, let me say thank you! thank you! thank you! for the extended EL in Seam. On a previous project, I was using straight JSF 1.1/1.2(Myfaces) and the extended EL alone, makes Seam a worthwhile choice.

This article is about an application that is relatively simple (to start). A report with customer information that has pretty charts and graphs and is printable to PDF. Since I didn't have any requirements to start, I thought I would list a few of my own here ;)

  • JSF & Seam
    • RESTful URL's
    • EJB3/Hibernate
    • Local, rapid, development
  • Maven 2
  • Charts
  • Html 2 PDF functionality

JSF & Seam

When I started development, Seam was at v.1.2, Embedded EJB (aka Embedded Jboss) was at RC9, and Jetty was being used for local dev and testing. I was able to get a jump start from the guys over at http://softeu.cz for the jetty/ejb/war deployment and I found a rouge project on the seam boards called JBossSeamDVDStore that gave me the ejb Maven archetype ideas/best practice.

I went through some good (and bad) code getting the embedded RC9 stuff working with Jetty. It boiled down to this post showing why and what I did.

The good and bad news now is that Embedded EJB3 is now Embedded Jboss and Embedded Jboss only works with Tomcat (for now) and here is a post explaining why it's this way. But this could also be a blueprint for creating the same thing for Jetty, I just don't have the time to do it right now.

Here is a list of resources I found useful while researching.

RESTful URL's

The #1 biggest complaint using JSF is no RESTful urls, and Seam does a great job of solving it. The only problem I have now is double execution when the user does a postback to a page that has a action mapped in pages.xml. The form I'm submitting calls the same action as the url I have mapped for REST support. I haven't spent alot of time with it and it may be total user error, but it would be nice if double action execution did NOT happen naturally.

EJB3/Hibernate

Using seam-gen, in Oracle, a few tables had null id fields and no primary key - The generated entity bean was genned as a object with one member (an ID) and I guess it was considering the entire record (all columns) as a unique. Being new to EntityBean/Generated hibernate code, it took us a few hours to figure this out, but once we saw that the data model was screwed up and how seam-gen handled it, the fix was easy.

Local, rapid, development

This was mentioned a little in the first paragraph. I wanted a faster, local build environment than what was currently offered by the company I'm working for. They are heavily tied to ant and there were 0 projects using Maven. So, being the completely crazy person that I am, I introduced a new build method with Maven 2, a new Framework wrapper (Seam), and a local build on the developers laptop with hot deploy. I know Jboss AS offers hot deploy, but I really wanted to use Jetty with Embedded Jboss. Since, that isn't currently implemented, I went with the next best thing and used Tomcat. My current company gives every developer a Solaris box to build on, all builds/projects are tied to building on Solaris. When one tries to use IntelliJ Idea over a Samba mount, you will quickly see how much it brings down overall performance and speed. There are other pluses that I could go into on local dev opposed to a remote *nix box, but I will stop here.

Maven 2

When you have 100's of projects on Ant and everyone in the company is pro Ant because so much time has been invested into the current build environment, you really feel like your going against the grain. However, most of us in the open source world, that are consultants, have seen the light on other projects and we bring new things into whoever we are working for. This is what I did. I eventually gained a few supporters, because everyone knows what happens when you are close minded to innovation.

Charts

I think using the Trinidad Charts are what WOW'd the upper management the most. Since this company has a distributed computing environment with no admin rights, we had to get the security/network folks on board with the Adobe SVG plugin. I heard the Renesis viewer is pretty good also and we will probably move to it later since Adobe is killing support on their plugin.

Html 2 PDF functionality

PD4ML: I started with this HTML2PDF renderer. It was super easy to get hooked up to the app. I structured my xhtml and css for both screen and print media types, but due to lack of CSS 2.1 support and very limited subset of css and html support, the output was terrible and required alot of rework just for this PDF to render half way decent. And it costs money :(

With the output coming out horrible in PD4ML, I took a look at a pure xhtml renderer, Flying Saucer.

FS Almost instantly rendered all of my XHTML correctly on the first render. I had to make a few adjustments for things like CSS page-break properties and border-collapse. And, before I could even get the page to render I had to clean up the legacy HTML that some JSF renderers output (I ran tests with both Jtidy and NekoHTML) - both did the trick and I couldn't tell a difference. All the JSF folks that I have talked to welcome feature requests for XHTML compliance.

This demo shows some pretty cool stuff from Flying Saucer and what it can do. It is basically the same concept of iTunes web browser/desktop app. PDF isn't the end of the road either - they have examples on rendering the exact same XHTML content to PNG, SVG, and Excel - I'm sure there will be more.

There are probably a million more things in Seam that I could talk about here, that I completely can't live without. This article just touches on the real world stuff that I encountered while developing.