Thursday, June 08, 2006

Stateful Thinking with JBoss-Seam

A couple of days back I listened to the great interview of Gavin King at JavaPosse. Lots of voices have been burnt over this interview in TSS and elsewhere. In the interview Gavin talks about Hibernate, EJB3, JSF and the latest from JBoss, Seam. He lambasted stateless architectures and dismissed the thought that stateful session beans do not scale as an ancient canard in the Java community. He made some insightful comments regarding the architecture of Seam and how the stateful and contextual components of Seam manage application state for POJOs.

The main reason why the above interview of Gavin has raised so many eyebrows is that it has hit the community right on the nail and has attacked the most pervasive architecture in today's Java EE space. Rod Johnson led Spring community has successfully evangelized the stateless architecture backed by the most mature IoC container, since the dark ages of EJB 1 and EJB 2. In his landmark book, Rod mentions
Applications that don't hold server-side state are usually the most scalable. In a web application, for example, if we need to hold only minimal user state, we might be able to hold it in cookies, avoiding any need for HTTP session state replication.

Give me a break! Can u have a meaningful enterprise application without any requirement for holding server-side state ? What about the conversational applications that thrive on long running business processes necessitating application state management in multiple contexts ? I guess the Extended Persistence Context (EPC) was designed in EJB specifically for this purpose. I personally have been an admirer of the Spring technology and the simple yet powerful programming model that it has evangelized leading to a significant impact in developer's productivity. But Gavin King definitely has a point, which all of us need to ponder over - one size doesn't fit all. As I mentioned in my last blog, the developer community needs to make the proper judgement before deciding whether to eat the elephant or not.

HTTPSession or SFSB ?

This is one of the questions that has been raging the floors and blogs of all Java EE developers. The Spring community thinks SFSBs are sin - maintain state (if required), in HTTPSession and use session state replication for scalability. They suggest minimal state on the server side using fine grained session objects, which can be easily replicated across servers. But, as I mentioned above, how do we handle optimistic transactions, long sessions, conversational applications ? Gavin is justified when he FUDs Spring on this ..
Huh? You don't have SFSBs (or anything equivalent). How could you implement EPC (optimistic transaction) support without difficulty? If you could do this without difficulty, why did you not do it years ago, and save Hibernate users from years of pain with LazyInitializationException?!

Enter Seam - a grand unification of the component models of JSF and EJB3. The mission - Deprecate the stateless architecture that we have learnt to adopt so naturally. Seam adopts SFSBs as the main container of managed application state - a theory that Gavin King believes in from way back in 2004 while ruminating on the notion of "application transactions" in a hotel room in Thailand.

Why does Gavin believe that HTTPSession is NOT the place to hold application state and that doing so is NOT scalable ?

In order to answer this, let us first assume that any meaningful enterprise application needs to maintain server-side state. In a clustered environment, replicating state for transparently managing failover is expensive. Typically SFSBs-are-unscalable-school architects adopt either of the following solutions (based on Gavin's presentation on Seam at JavaOne) :

  • Maintain state in the database. This is very expensive since it involves heavy I/O with the slowest layer in the tier. Inevitably they land up with a second level cache that needs to be kept transactionally consistent between the database and every node on the cluster – even more expensive!

  • Maintain state in HttpSession as JavaBeans. This has 2 problems -


    • The contract for HttpSession does not have dirty-checking - session replication means a bulk copy of the entire coarse grained object across servers. Though implementations like JBoss HttpSession and caching solutions like Tangosol Coherence offer attribute level buddy replication, it is definitely not the standard. Hence u need to re-set the attribute each time you change the bean state, which is extremely bug-prone and difficult to test.

    • A JavaBean is not transactional - hence u need to have an indirection of the session stored JavaBean through SLSBs for implementing business logic.



OTOH, SFSBs are managed by the container, provides complete transaction semantics and JBoss SFSB, being implemented on top of JBossCache provides attribute level replication. Hence stateful session beans provide much richer semantics than the dumb JavaBeans. Cool Stuff! An application which involves long transactions needs to maintain conversational states in multiple contexts - Seam scaffolds all these state management under the hood of stateful session beans as contextual components. Hence what we get is an efficient implementation for EPC. Of course, in order to synchronize the lifecycle of the SFSBs with the session events, we need to maintain a ref/handle/proxy of the bean in the HttpSession. Even the new session scoped beans introduced in Spring 2.0 will not be able to offer an as efficient implementation, since HttpSession is not the suitable place to keep this "big" information and will have the usual problems of clusterability.

Lessons Learnt

Stateful session beans are not as black as they are painted. In fact they may be the best bet to store the application state. And Seam exploits these capabilities to the fullest and provides a very elegant framework to model conversational applications. So, keeping in line with my last post, I would like to end this musing with the belief that we, the developers should not be carried away by the current hype that open source Java has created. The developer community should always try to embrace the standards, critique the standards and make the standards better instead of trading it for an implementation.

9 comments:

Anonymous said...

My understanding is Spring is an invasive framework and I'm sure that Spring 2.0 will work fine with EJB 3.0.

I agreed with Gavin that Spring doesn't not provide anything similar to SFSB in Spring. However, if I need "long life txn", I can still use SFSB alongside with Spring POJO in managed envirnoment (or JTA container). I can still manage by transaction using spring declarative AOP txn manager.

Is there any thing wrong to use SFSB and Simple Java Class together??

Spring is complement with JEE, it just something to make your life a bit easier. The main reason that I like Spring over JBoss Seam is it intergrate wells will many third-party library. E.g. It intergrates will jBPM with Spring Modules, unlike Seam, it ONLY intergate with jboss's product. JBoss's products are great. However, I perfer I have different options.

In spring 2.0, I can inject any POJO service into my domain model to avoid the famous anti-pattern "Anemic Domain Model" (named by Martin Flower).

In EJB3, can I inject a session bean into an entity bean? can I put business logic into my domain model? Can some EJB3 expert clarify this for me please?

Anonymous said...

Usage of infrastructural solutions that are intended to avoid LazyInitializationException (LIE) increases the risk of an inefficient application design. Examples of this are the Open Session In View (OSIV) and EJB3's Extended Persistence Context (EPC) patterns.

LazyInitializationException is not a pain, nor a burden. It's a whisleblow, an indication that's somehow something's wrong in the application design.

In web applications, the occurance of LIE most likely means supporting service (for example, components of a service layer) don't properly fit the web layer.

I'm not going to go into detail here on how to avoid LIE. The crux of the matter is that use of OSIV or EPC is dangerous because you shut up the whisle.

When you no longer get early warnings about potential problems with your application design you may only become aware of inefficiencies when you've come at a point where making changes costs a lot of money.

Studying your design in large projects when LIE first manifests itself is very likely to be much more cost efficient.

On a side note: people have been managing state on the server side for many, many years using distributed, transactional caches and technologies like JavaSpaces. These are products that are less expensive as you may think. Don't believe stateful session beans is the only answer in the Java enterprise space to that.

Debasish said...

Why do u say that EPC is meant to shut up LIE ? EPC has its own use in modeling conversational applications - JBOSS Seam offers contextual components at various levels of granularity. Managing state in Web applications has been a problem since time immemorial and people have been using all sorts of workarounds like using HttpSession, database or caching solutions. None of these scale well enough - don't u think SFSBs provide a better solution and an ideal place to handle states.

Anonymous said...

debasish said: "Why do u say that EPC is meant to shut up LIE ? EPC has its own use in modeling conversational applications - JBOSS Seam offers contextual components at various levels of granularity."

You misunderstood, I'm not saying EPC is meant to avoid LIE. I'm saying it's avoiding the occurence of LIE regardless whether it's meant to do so or not.

debasish said: "Managing state in Web applications has been a problem since time immemorial and people have been using all sorts of workarounds like using HttpSession, database or caching solutions. None of these scale well enough - don't u think SFSBs provide a better solution and an ideal place to handle states."

I think you're not familiar with the scalability of cache engines. There are many Java enterprise applications out there based on transparent, distributed state management that are not using stateful session beans.

And an application that has a web interface - no matter how ellaborate - is not necessarily a "web application". There are other options for storing state than the HTTP session, the database and stateful session beans.

Stateful session beans sure have their use and in the big book of all state-based use cases they cover a modest percentage.

It's important for developers working on large applications to recognize there are many use cases based on state management that are not using stateful session beans and would not benefit from using them.

In fact, by asuming stateful session beans are "ideal" for "web applications" you're blinding yourself for a host of very interesting usage patterns involving state management that can be beneficial for your applications and will result in more flexible designs.

Debasish said...

anonymous said: I think you're not familiar with the scalability of cache engines.

My mistake. I did not want to say that caching solutions do not scale - I meant that for managing states with databases and HttpSessions. I am familiar with Coherence from Tangosol and Terracotta Clustered JVMs and both of them scale very well.

My point of the post was that the contextual components offerred by Seam present to developers a very convenient way of modeling conversation based Web applications. Users can continue multiple stateful conversations simultaneously using contextual SFSBs.

I would like to know ur impressions on SFSBs and the ways they have been used in Seam. Also how do u view Seam as an alternative architectural platform compared to Spring(which encourages stateless architectures).

Anonymous said...

debasish said: "My point of the post was that the contextual components offerred by Seam present to developers a very convenient way of modeling conversation based Web applications. Users can continue multiple stateful conversations simultaneously using contextual SFSBs."

This comes at a cost. You won't get LIE to warn you about possible design inefficiencies early on. And the modelling approach Seam takes is geared towards prototyping.

There's no switch in Seam that allows you to use EPC yet get LIE.

If you browse through the Seam forum you'll find that many customizations developers want to implement when migrating from prototype to production are simply not possible due to the use of EPC and stateful session beans.

Seam doesn't depend on EPC - it's a matter of configuration - but you'll find that the model offered without EPC is inferior.

Seam offers a limited model that if you want to go beyond this leaves you in the cold. This is typical for specifications, think EJB3, JPA, JTA.

I often hear the same argument: specifications need time to grow. Businesses and organizations don't have the luxury to wait. They have to rely on competitive advantages offered by the tools they adapt to outsmart and outperform they competitors by reducing time to market, improve cashflow, reduce costs, respond quickly to customer demands and market evolutions, ... .

Frameworks like Spring that are extremely flexible and extensible offer the kind of short iterative improvements businesses and organizations need.

Some features in Spring can be hard to configure or aren't as well documented as they could be, but the functionalities are available and there are many Spring experts that can help you out. And more importantly, Spring 2.0 has superior configuration options thanks to custom XML Schema support.

Seam is a black box. Some customizations that go beyond the specification are possible depending on the application server you're using but the limitations largely remain.

Spring is a toolkit where you can cherry pick the features you need. For example, Spring Web Flow offers a much more flexible model than Seam, one that businesses and organizations can extend far beyond what Seam offers and much of it comes out of the box.

debasish said: "Also how do u view Seam as an alternative architectural platform compared to Spring(which encourages stateless architectures)."

Spring encourages many architectures, not only stateless. The state scoping support that's now available in Spring 2.0 offers powerful state management. If you want to scope state against web conversations there's Spring Web Flow. If you want to use state orchestration along the lines of business processes there's Mule's integration with Spring.

There are so many state management scenario's out there. Spring supports all of them (application server vendors are using Spring to implement stateful session beans) and Seam only supports a few. Even Seam's web conversation model doesn't offer the kind of flexibility and extensibility developers need.

I sometimes hear managers saying they stick to specifications all the way because they want to make their applications and products future proof. This is a misguided decision both from an economical and a technical point of view.

From an economical perspective applications and products need to adapt to changes on the short term. The risk that a tool will be outdated in a number of years is dwarfed by the risk of not being able to think and act beyond what's offered by specifications on the short term.

What's the biggest risk: being blamed for not using specifications or being blamed for not being able to adapt to changes efficiently?

Anonymous said...

debashis said: "Even the new session scoped beans introduced in Spring 2.0 will not be able to offer an as efficient implementation, since HttpSession is not the suitable place to keep this "big" information and will have the usual problems of clusterability."

You are misinformed if you believe Spring 2.0 can only use the HTTP session as an object store.

Debasish said...

anonymous said: You are misinformed if you believe Spring 2.0 can only use the HTTP session as an object store.

The current spring reference documentation does not yet contain any meaningful information regarding the session scoped beans, though the section 3.2.3 New Bean Scopes refer to Section 4.2.5 Bean Scopes. I could not find any meaningful information in 4.2.5. I think the documentation has not yet been updated. The fact that the session scoped beans use HttpSession as the store was present in some discussion which I located on the net.

Will appreciate any info / pointers regarding best practices to be used for state management in Spring based implementations, when I am modeling a conversation based application.

Also if u can give me some pointers regarding the new scoped beans in Spring 2.0.

Ilya Sterin said...

In spring 2.0, I can inject any POJO service into my domain model to avoid the famous anti-pattern "Anemic Domain Model" (named by Martin Flower).

Ha? Please reread that material, not sure what you mean by injecting a POJO service into the domain model. You're domain model is POJO's and you can inject any dependency into any POJO.

In EJB3, can I inject a session bean into an entity bean? can I put business logic into my domain model? Can some EJB3 expert clarify this for me please?

Ha? The whole point of POJO based domain models is the fact that you can avoid the anemic domain model and actually have a truly OO application by defining business logic in object behavior.