Introduction to JBoss Seam Framework
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
Less noise
Simple Object-Relational Mapping (ORM)
JSF is flexible and extensible
JPA
Some disadvantages of using plain JSF are:
JSF
How do we write our business layer
And then there are some more challenges which are:
Workflow
Multi-tab/window support is not built in
However, JSF does provide certain advantages which are:
JSF
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)?
The Persistence Context has a flexible scope
Which PC scope to use in JPA?
Transaction scoped & detached objects
An extended persistence context of a SFSB is
PC has no concept of a conversation
Advantage of SEAM managed persistence and transactions
What else does SEAM give us?
SEAM 2.1 Roadmap - The near future

Save to Browser Favorites
Ask
backflip
blinklist
BlogBookmark
Bloglines
BlogMarks
Blogsvine
BUMPzee!
CiteULike
co.mments
Connotea
del.icio.us
DotNetKicks
Digg
diigo
dropjack.com
dzone
Facebook
Fark
Faves
Feed Me Links
Friendsite
folkd.com
Furl
Google
Hugg
Jeqq
Kaboodle
kirtsy
linkaGoGo
LinksMarker
Ma.gnolia
Mister Wong
Mixx
MySpace
MyWeb
Netvouz
Newsvine
PlugIM
popcurrent
Propeller
Reddit
Rojo
Segnalo
Shoutwire
Simpy
Slashdot
Sphere
Sphinn
Spurl.net
Squidoo
StumbleUpon
Technorati
ThisNext
Webride
Windows Live
Yahoo!
Email This to a Friend
If you like this then please subscribe to the
Rocks Said,
July 18, 2008 @ 1:01 pm
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
Ashish Kulkarni Said,
July 21, 2008 @ 12:19 pm
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 Said,
July 29, 2008 @ 12:57 pm
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 Said,
July 29, 2008 @ 1:03 pm
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
ashish Said,
August 1, 2008 @ 10:06 am
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 Said,
August 4, 2008 @ 10:03 am
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
Ashish Kulkarni Said,
August 7, 2008 @ 1:34 pm
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 Said,
August 16, 2008 @ 9:23 pm
Your blog is interesting!
Keep up the good work!
Rocks Said,
August 28, 2008 @ 12:58 pm
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 Said,
September 26, 2008 @ 8:01 am
Hi Ashish!
I’m newbie with Seam. Can you please show me how to build tree component in Seam?
ashish Said,
September 29, 2008 @ 3:34 pm
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 Said,
September 30, 2008 @ 9:31 am
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 Said,
November 11, 2008 @ 1:34 pm
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.
ashish Said,
November 14, 2008 @ 10:53 pm
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 Said,
November 17, 2008 @ 3:02 pm
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