Before introducing JBoss SEAM Framework, I would like to put some background into perspective first.

Most Java Developers are aware of Model-View-Controller (MVC) frameworks such as Struts and more recently JavaServer Faces or JSF. JSF + Java Persistence API (JPA) combination have a lot of advantages over Struts + EJB 2 combination. These are as follows:

Fewer, finer grained artifacts

  • No Data Transfer Objects (DTOs) required
  • Clean MVC

Less noise

  • No Struts/EJB 2.x boilerplate code
  • No direct calls to HttpSession or HttpRequest

Simple Object-Relational Mapping (ORM)

  • Even simpler than the Hibernate API!

JSF is flexible and extensible

  • Custom UI widget suites (open source)
  • Good AJAX support

JPA

  • Powerful object/relational mapping, far beyond EJB 2.x CMP entity beans
  • All components are POJO so easily testable with TestNG or JUnit

Some disadvantages of using plain JSF are:

JSF

  • Backing bean couples layers and is just noise
  • Hard to refactor all the XML and String outcomes
  • No support for the business layer
  • Validation breaks DRY
  • XML is too verbose

How do we write our business layer

  • EJB3? – Unfortunately it can’t be used directly by JSF
  • EJB3? – It has no concept of scopes

And then there are some more challenges which are:

Workflow

  • Ad-hoc back buttoning not suppored
  • No stateful navigation
  • No support for long running business processes

Multi-tab/window support is not built in

  • All operations happen in the session – so there is memory leakage
  • No support for a conversation context – so wizards have to use Session Scoped objects
  • Memory leak – objects don’t get cleaned up quickly

However, JSF does provide certain advantages which are:

JSF

  • Validation code in the front-end – for example, required=”true” for input fields.
  • Provides converters for Dates, Amounts, etc.
  • Allows calling Business Layer functions directly.
  • Provides a way for outputting messages alongwith severity (error, info, etc.)

Let us now talk about what SEAM brings to the table.

SEAM allows us to Begin and End a conversation – State is maintained over multiple requests
between Begin and End.

For example:


@Name("itemEditor")
@Scope(CONVERSATION)
public class EditItemBean implements EditItem {

@In EntityManager entityManager;
Long id;
Item item;

// getter and setter pairs
@Begin public String find(Long id) {
item = entityManager.find(Item.class, id);
return item == null ? "notFound" : "success";
}

@End public String save(Item item) {
item = entityManager.merge(item);
return "success";
}

}

Following Scopes are available when we make use of SEAM:

Event – Same as Http Request Scope
Page – New to SEAM – Used just for rendering output
Conversation – New to SEAM – Spans several requests
Session
Application
Business Process – New to SEAM – Spans several conversations and even survives Server restart

As you can see, SEAM makes a few new Scopes available to us which are Page, Conversation and Business Process.

How does SEAM store the state information? Well, that depends upon the context we are talking about.

In Page context, the state information is stored in the component tree of the JSF view (page). It can also be stored in HttpSession or serialized to client.

For conversation context, SEAM stores the state information in a Segmented HttpSession. This information times out if not used thus, preventing Memory Leaks.

In Business Process context, the state information is Persisted to database, and is handled by jBPM.

What is Bijection?

Unlike Spring Framework, which only allows Dependency Injection, SEAM allows Dependency Bijection.


@Name("passwordChanger")
public class PasswordChanger {

@In EntityManager entityManager;
@In @Out User currentUser;

public void changePassword() {
entityManager.merge(currentUser);
}

}

In the above example, entityManager is being Injected whereas, currentUser is both injected as well as outjected.

As a result, currentUser’s value will be first made available to changePassword() and then, once it is done, the objected will be made available to whoever needs it.

Scope of currentUser itself will be governed by the scope of the User class.

A brief explanation about JPA Persistence Context

What is the Persistence Context (PC)?

  • It is a HashMap of all the objects I’ve loaded and stored
  • It holds (at most) one in-memory object for each database row while the PC is active
  • It is a natural first-level cache
  • It can do dirty checking of objects and write SQL as late as possible (automatic or manual flushing)

The Persistence Context has a flexible scope

  • default: same scope as the system transaction (JTA)
  • extended: the PC is bound to a stateful session bean

Which PC scope to use in JPA?

Transaction scoped & detached objects

  • LazyInitializationException
  • NonUniqueObjectException
  • Less opportunity for caching

An extended persistence context of a SFSB is

  • not available during view rendering (LIE again)
  • very complicated propagation rules

PC has no concept of a conversation

Advantage of SEAM managed persistence and transactions

  • SEAM managed PC is conversation scoped.
  • It remains active through conversation,
  • It is injected using @In – @In EntityManager entityManager
  • It allows use of manual flush mode

What else does SEAM give us?

  • Security – This can be configured to work at Page, Field, Class, Method or custom level.
  • Email templates
  • PDF templates
  • JavaScript Remoting
  • Asynchronicity (Java SE, EJB3 or Quartz)
  • Provide Google-style search in your app using Hibernate Search
  • Integration and Unit Testing
  • JSF components (deep integration into JPA)
  • Support for RichFaces, ICEFaces and Adobe Flex 3 RIA
  • Components in groovy
  • WebServices
  • More than 25 examples
  • Portal support
  • Validation
  • BPM support
  • Stateful navigation

SEAM 2.1 Roadmap – The near future

  • Providing Wicket as a view layer
  • Providing GWT as a view layer
  • First class support for other other containers (e.g. Websphere)
  • Identity Management
  • Single-Sign-On for security
  • Deeper integration with JBoss Portal (inter-portlet communication)

27 Responses to “Introduction to JBoss Seam Framework”

  • Rocks:

    Hi Ashish

    I am having few queries.
    1: I use a sample application and when i run that i got the exception
    “Target unreachable identifier ‘user’ resolved to be null”
    when i saw the logs i found that Seam scanner was scanning my Seam component jar and also putting them in the relevant scope, e.g
    2008-07-18 16:12:42,225 INFO [org.jboss.seam.Component] Component: userbean, scope: APPLICATION, type: ENTITY_BEAN, class: com.rp.seams.UserBean

    but when i was using that on my jsf page, i was greeting the above mentioned exception.

    and then I add @Startup annotation in the class, and i got below info on my server log
    2008-07-18 16:12:42,240 INFO [org.jboss.seam.contexts.Contexts] starting up: userbean
    2008-07-18 16:12:42,240 DEBUG [org.jboss.seam.Component] instantiating Seam component: userbean
    2008-07-18 16:12:42,240 DEBUG [org.jboss.seam.Component] initializing new instance of: userbean
    2008-07-18 16:12:42,240 DEBUG [org.jboss.seam.Component] done initializing: userbean

    after that on my JSF page everything starts working fine.

    Please can you describe the@Startup, bcoz we cant use this in every class, as it requires the Scope of Application/Session which i think not suitable for every java bean.

    Please suggest.

    2: take base as the first query.
    now on my JSF form i have two fields
    name :- #{user.name} — binded to my seam component “User”
    last name :- #{user.lname} — binded to my seam component “User”
    and submit button :- #{register.register} — binded to my seam component “RegisterAction”

    when i am submitting the form i am getting the below exception.
    java.lang.NoSuchMethodError: javax.faces.component.UIComponent.getValueExpression(Ljava/lang/String;)Ljavax/el/ValueExpression;
    org.jboss.seam.ui.validator.ModelValidator.validate(ModelValidator.java:28)
    javax.faces.component.UIInput.validateValue(UIInput.java:801)
    javax.faces.component.UIInput.validate(UIInput.java:665)

    Please suggest

    Thanks
    Rocks

  • Hi Rocks,

    My first observation is that your component is called “userbean”. Whereas, you are using the name “user” in your JSF. Hence, the errors.

    Second observation relates to the scope. In seam, you have a scope called “conversation”. Behind the scenes, this scope uses a segment within your HTTPSession. But in practical terms, it gets rid of objects if they are not accessesed for a specific length of time.

    You can specify that your userbean is of conversation scope by adding the following declaration at the top of the UserBean class:

    @Scope(ScopeType.CONVERSATION)

    You can then begin the conversation either using <begin-conversation /> within your page.xml file and end it by adding <end-conversation /> in page.xml for the action register.register as follows:

    <navigation from-action=”#{register.register}”>
    <end-conversation />
    <redirect view-id=”/users/usersList.xhtml” />
    </navigation>

    Let me know if this helps.

    Best Regards,

    Ashish.

  • Rocks:

    Hi Ashish

    Thanks for the help. I still have few doubts.
    1: Can you please explain the Conversation Scope a bit more in detail.
    2: For a blank seam application war file, what are th required Jars/.xml files.
    3: Can we use seam without EJB.
    4: Suppose i have a servlet and i have to access user defined seam component inside that, Can you please provide the syntax to find that component. if possible to do so.

    Thanks again for your valuable help.
    cheers!!!
    Rocks

    P.S Buddy you are doing great job, i must say this :)

  • Rocks:

    Hi Ashish

    Also one more query.
    In which scenario we use @In and @Out.
    I haven’t worked on EJB and Spring, due to that, these annotations are becoming a nightmare for me. lol!!!!

    Thanks
    Rocks

  • Hi Rocks

    Thanks for the help. I still have few doubts.
    1: Can you please explain the Conversation Scope a bit more in detail.
    2: For a blank seam application war file, what are th required Jars/.xml files.
    3: Can we use seam without EJB.
    4: Suppose i have a servlet and i have to access user defined seam component inside that, Can you please provide the syntax to find that component. if possible to do so.

    Thanks again for your valuable help.
    cheers!!!
    Rocks

    P.S Buddy you are doing great job, i must say this

    Rocks Said,
    Hi Ashish

    Also one more query.
    In which scenario we use @In and @Out.
    I haven’t worked on EJB and Spring, due to that, these annotations are becoming a nightmare for me. lol!!!!

    Thanks
    Rocks

    Hi Rocks,

    Apologies for the delay in response.

    1. Imagine a multi-page wizard where you would need to populate bits of a form as you go along. In a traditional J2EE application you would use the Session scope for this. But imagine if your user navigated away from the website or closed the browser or even clicked on another link within your own site. All the objects related to your form will remain in memory on your server. This is where the conversation scope helps. It times out objects and makes them available for garbage collection even if the session itself is still alive.

    2. If you start with seam-gen and go through the setup, create-project, generate and explode steps, what you will have in the dist folder is the jar and xml files. And if the database you got the app to connect to has no tables, then the generated application will be blank :-) .

    FYI, I use MyEclipse and have got an Enterprise Application Project. My directory structure (without any project specific files) looks like the following:

    Folder PATH listing
    C:.
    |
    +—webshop
    | | .mymetadata
    | | .project
    | | hibernate-validator.jar
    | | jboss-seam.jar
    | |
    | +—lib
    | | antlr-runtime.jar
    | | core.jar
    | | drools-compiler.jar
    | | drools-core.jar
    | | janino.jar
    | | jboss-el.jar
    | | jbpm-jpdl.jar
    | | mvel14.jar
    | | richfaces-api.jar
    | |
    | \—META-INF
    | application.xml
    | jboss-app.xml
    |
    +—webshopEJB
    | | .classpath
    | | .mymetadata
    | | .project
    | |
    | +—classes
    | \—src
    | | seam.properties
    | | security.drl
    | |
    | +—com
    | | \—sfbl
    | | +—action
    | | | Authenticator.java
    | | |
    | | \—model
    | |
    | \—META-INF
    | ejb-jar.xml
    | persistence.xml
    |
    \—webshopWeb
    | .classpath
    | .mymetadata
    | .project
    |
    +—src
    | messages_bg.properties
    | messages_de.properties
    | messages_en.properties
    | messages_fr.properties
    | messages_tr.properties
    |
    \—WebRoot
    | error.xhtml
    | home.xhtml
    | index.html
    | login.page.xml
    | login.xhtml
    |
    +—img
    | dtpick.gif
    | error.gif
    |
    +—layout
    | display.xhtml
    | edit.xhtml
    | menu.xhtml
    | template.xhtml
    |
    +—stylesheet
    | theme.css
    |
    \—WEB-INF
    | components.xml
    | faces-config.xml
    | pages.xml
    | web.xml
    |
    +—classes
    | messages_bg.properties
    | messages_de.properties
    | messages_en.properties
    | messages_fr.properties
    | messages_tr.properties
    |
    \—lib
    commons-beanutils.jar
    commons-digester.jar
    jboss-seam-debug.jar
    jboss-seam-ioc.jar
    jboss-seam-mail.jar
    jboss-seam-pdf.jar
    jboss-seam-remoting.jar
    jboss-seam-ui.jar
    jsf-facelets.jar
    richfaces-impl.jar
    richfaces-ui.jar

    This should give you an idea of what files are needed and where should they go.

    3. Of course you can create a seam App without using EJBs. However, Seam itself uses EJBs. So you do need an EJB container such as JBoss.

    4. Assuming that the component is in session or conversation scope, defined as “user” and is of type User, you can access it within your servlet in the following ways:

    @In User user; (Seam will automatically inject the user object if it can find it).

    public String myFunction()
    {
    if (“”.equals(user.getMidName())
    {
    // Some code like this to use the injected object.
    }
    }

    Alternatively, you can also use EL expression such as “#{user.midName}”.

    5. Well buddy, you better get used to annotations because there are lot more of them than just @In and @Out.

    You will use @In to get Seam to inject an object and @Out to outject it. The scope of the outjected object depends upon the scope defined in its class.

    For example, in authenticator class, you want to check a user’s credentials and if they are correct, you want to set the user in session scope. This is how you would do it:

    User.java:

    @Name(“user”)
    @Scope(ScopeType.SESSION)
    public class User implements Serializable
    {
    // attributes, getters and setters here
    }

    Authenticator.java:

    @Name(“authenticator”)
    public class Authenticator {

    @Logger Log log;
    // For logging – another annotation – @Logger to get hold of the logger :-)

    @In Identity identity;
    // We use this to keep hold of username, password and other security information

    @In @Out User user;
    // Notice here that we are outjecting the user object

    @In EntityManager entityManager;
    // Notice that we are getting seam to inject entityManager – the object that helps us access database.

    public boolean authenticate()
    {
    // Your authentication logic below
    if (…user is authenticated…)
    {
    return true;
    }
    else
    {
    return false;
    }
    }
    }

    Hope this helps.

    Best Regards,

    Ashish.

  • Rocks:

    Hi Ashish

    Thanx a lot for the reply.
    Buddy I have started looking into EJB 3, Actually I have worked most on Struts in my career. Now just getting ready for the new thing :) , But I have found it(seam) very good and interesting.

    Once again Thanx brother for your valuable suggestions.

    Cheers
    Rocks

  • Hi Rocks,

    I have myself worked on Struts for over 7 years and find Seam + JSF much easier to digest.

    All the best.

    Regards,

    Ashish.

  • Alex:

    Your blog is interesting!

    Keep up the good work!

  • Rocks:

    Hi Ashish

    Hope your doing good?
    I Have a query, Suppose i have five ejb components defined using Seam, How can i access those outside the seam layer, I mean in a servlet, is there any way where i can get the current seam Context and search the components inside it.
    please suggest how we can access using java code e.g java code syntax.

    thanks
    Rocks

  • hung:

    Hi Ashish!
    I’m newbie with Seam. Can you please show me how to build tree component in Seam?

  • Hi Hung,

    What kind of tree component are you after?

    Have a look at http://livedemo.exadel.com/richfaces-demo/richfaces/tree.jsf

    Best Regards,

    Ashish.

  • hung:

    Hi Ashish!
    I looked at http://livedemo.exadel.com/richfaces-demo/richfaces/tree.jsf and built Default Tree Model same example(http://livedemo.exadel.com/richfaces-demo/richfaces/tree.jsf?tab=model).
    But I have problem with nodeSelectListener.

    In my TreeBean.xhtml:

    In SimpleTreeBean.java I have method: public void processSelection(NodeSelectedEvent event).

    Error: [lifecycle] /TreeBean.xhtml @18,260 nodeSelectListener=”#{simpleTreeBean.processSelection}”: java.lang.reflect.InvocationTargetException

    Could you give me some advice?
    Thanks!

  • Rocks:

    Hi Ashish

    Hope you doing great,
    I am having a query, is there any caching thing available in Seam, i want to cache some data in user specific mode, so that we don’t have to make necessary calls to database. please suggest.

    Also if we Inject and Outject some objects, is it possible to change the object without using @Out in some another action class.

    Please suggest.

  • Hi Rocks,

    I have a need to do something similar to store a user’s menu which comes from the database based upon user authorisations. However, I don’t want to keep hitting my database every time a new page is displayed.

    What I do is I create a userMenu object which has a ScopeType.SESSION and outject it from my Authenticator class.

    You can access objects using EL notation as well. I haven’t try to modify that way though :-) .

    Cheers,

    Ashish.

  • Bayapa Reddy Patil:

    Hi Ashish,

    I have a burning requirement in Seam. I have a simple plain POJO class without having any seam annotations. Now in my action class I require to have this pojo injected and outjected and maintain in conversation scope. I have done both those annotation while creating an instance in the Action class. But the session is ending in the once the response is back to the browser. Is there any mode for specifying the scope at Action level for a plain Java Object. If so, please let me know immediately as it is very urgent.

    Thanks in Advance.
    Regards,
    Bayapa Reddy

  • Hi Bayapa,

    Seam allows the following scopes:

    APPLICATION
    The application context (Servlet context.)
    BUSINESS_PROCESS
    The business process context.
    CONVERSATION
    The conversation context.
    EVENT
    The event (request) context.
    METHOD
    The method context.
    PAGE
    The page context.
    SESSION
    The session context.

    Unfortunately without knowing much about your application or looking at your code, I cannot write more specific response.

    Best Regards,

    Ashish.

  • zmshang:

    hi,ashish

    I have problem with nodeSelectListener, just like hung. can you give some advice?

  • Where exactly is this hanging?

    Can you see the request going through to the server? Or is it hanging at the client side itself?

    Cheers,

    Ashish.

  • Mahesh:

    Hi

    Ashish

    I have some problem with scrollableDataTable.
    When project is run for first time. The Header of columns are display but when we refresh it it can be disapper.

    Following is my Code

    Refrence Article

    Designation Article

    valure Unitaire

    N Lot Frs.

    Nombre UC

    Nombre Pieces

    Poids Brut(Kg)

    Poids Net(Kg)

    Total Valuere

    Unite

    UC Non Stocker

    Date Preemption

  • Hi Mahesh,

    Sorry, I didn’t get your question. Can you please elaborate?

    Best Regards,

    Ashish.

  • Panduka:

    Hi ashish,

    I’m trying to setup security in application by using seam/LDAP.

    Up to now I was able to connect with OpenLDAP server in seam application by setting component.xml(acording to the given in seam reference document. I’m sure it is connecting to LDAP as if wrong credential throw exception and correct UserId/PWD nothing returned. So, there is no document to find saying how to handle the Identitystore, LdapIdentitystore…….. classes or at least a sample code. Can you help me on this?

    Regards
    Panduka

  • [...] recorded first by hjortholm on 2009-02-04→ Introduction to JBoss Seam Framework [...]

  • rocks:

    Hi Ashish

    Hope you are good in spirits.

    Can you please give me some code snippet of storing value in session object inside seam component. actully i have a list object and i want to store this in session object.

    @In(value = “list”, scope = ScopeType.SESSION, required = false)
    @Out(value = “list”, scope = ScopeType.SESSION, required = false)
    List list;

    i have used the above one, but it does not working fine.

    Please suggest..

    Thanks
    Rocks

  • Bhaskar:

    Hi Ashish,
    Nice post..!!
    I am trying to move write a simple seam app without using EJB as I am using JBoss, is there any special configuration needed for persistence context?

  • Thanks.

    You don’t need any special configuration unless you are trying to do anything out of the ordinary.

    Regards,

    Ashish.

  • sathish:

    hi i was new to seam .
    i am going to develop an application . in that i am displaying some entity objects using datamodel and datamodelselection in rich:datatable. when i select a row and going to change some column field it automatically updating on entity objects. i need to restrict this auto updation in my application. how would i achieve this?

    Thanks in advance
    sathish

  • Aditi:

    Hi Ashish,
    I’m newbie with Seam.I read all the comments related to this post.but can u please elaborate little more about Conversation Scope in SEAM.when we should use this and all.

    thanks in advance.

Leave a Reply

*


nine − 5 =