Wednesday, November 21, 2007

Stateful and Stateless EJB sample

Wednesday, November 21, 2007 Posted by Andre Broers 6 comments
In this example I show the difference between Stateful en Stateless EJB's. First I create and deploy the stateful bean.

broersa@debian1:~/work/HelloApp/HelloStateful/src/com/bekijkhet$ cat HelloStateful.java

[sourcecode language="java"]

package com.bekijkhet;
public interface HelloStateful {
public String sayHelloStateful();
public String sayHelloStatefulRemote();
public void setMember(String member);
}

[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloStateful/src/com/bekijkhet$ cat HelloStatefulLocal.java
[sourcecode language="java"]

package com.bekijkhet;
public interface HelloStatefulLocal {
public String sayHelloStateful();
public String sayHelloStatefulLocal();
public void setMember(String member);
}[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloStateful/src/com/bekijkhet$ cat HelloStatefulBean.java
[sourcecode language="java"]

package com.bekijkhet;
import javax.ejb.Stateful;
import javax.ejb.Remote;
import javax.ejb.Local;
@Stateful
@Remote(HelloStateful.class)
@Local(HelloStatefulLocal.class)
public class HelloStatefulBean implements HelloStateful,HelloStatefulLocal {

private String member = "Not set!";

public String sayHelloStateful() {
return "Hello Stateful "+member;
}
public String sayHelloStatefulLocal() {
return "Hello Local Stateful "+member;
}
public String sayHelloStatefulRemote() {
return "Hello Remote Stateful "+member;
}
public void setMember(String member) {
this.member=member;
}
}[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloStateful$ cat build.xml
[sourcecode language="XML"]



simple example build file













description="compile the source " >




description="generate the distribution" >







description="clean up" >




[/sourcecode]
Then build: asant distThen deploy: asadmin deploy dist/HelloStateful.jarNow the stateless bean:

broersa@debian1:~/work/HelloApp/HelloStateless/src/com/bekijkhet$ cat HelloStateless.java

[sourcecode language="java"]

package com.bekijkhet;
public interface HelloStateless {
public String sayHelloStateless();
public String sayHelloStatelessRemote();
public void setMember(String member);
}

[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloStateless/src/com/bekijkhet$ cat HelloStatelessLocal.java
[sourcecode language="java"]

package com.bekijkhet;
public interface HelloStatelessLocal {
public String sayHelloStateless();
public String sayHelloStatelessLocal();
public void setMember(String member);
}

[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloStateless/src/com/bekijkhet$ cat HelloStatelessBean.java
[sourcecode language="java"]

package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.ejb.Local;
@Stateless
@Remote(HelloStateless.class)
@Local(HelloStatelessLocal.class)
public class HelloStatelessBean implements HelloStateless,HelloStatelessLocal {

private String member = "Not set!";

public String sayHelloStateless() {
return "Hello Stateless "+member;
}
public String sayHelloStatelessLocal() {
return "Hello Local Stateless "+member;
}
public String sayHelloStatelessRemote() {
return "Hello Remote Stateless "+member;
}
public void setMember(String member) {
this.member=member;
}
}

[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloStateless$ cat build.xml
[sourcecode language="XML"]



simple example build file













description="compile the source " >




description="generate the distribution" >







description="clean up" >




[/sourcecode]
And finally the client:broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloStatefulClient.java
[sourcecode language="java"]

package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.HelloStateful;
import com.bekijkhet.HelloStateless;
public class HelloStatefulClient {
public static void main(String[] args) {
try {
InitialContext ctx = new InitialContext();
HelloStateful h = (HelloStateful)ctx.lookup("com.bekijkhet.HelloStateful");
HelloStateful i = (HelloStateful)ctx.lookup("com.bekijkhet.HelloStateful");
System.out.println(h.sayHelloStateful());
h.setMember("Initialized!");
System.out.println(h.sayHelloStateful());
System.out.println(i.sayHelloStateful());
}
catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
try {
InitialContext ctx = new InitialContext();
HelloStateless j = (HelloStateless)ctx.lookup("com.bekijkhet.HelloStateless");
HelloStateless k = (HelloStateless)ctx.lookup("com.bekijkhet.HelloStateless");
System.out.println(j.sayHelloStateless());
j.setMember("Init!");
System.out.println(j.sayHelloStateless());
System.out.println(k.sayHelloStateless());
}
catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
}[/sourcecode]
broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloStateful/dist/HelloStateful.jar:$HOME/work/HelloApp/HelloStateless/dist/HelloStateless.jar:. -d . HelloStatefulClient.javaRun for the first time:

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloStateful/dist/HelloStateful.jar:$HOME/work/HelloApp/HelloStateless/dist/HelloStateless.jar:. com.bekijkhet.helloclient.HelloStatefulClient
Hello Stateful Not set!
Hello Stateful Initialized!
Hello Stateful Not set!
Hello Stateless Not set!
Hello Stateless Init!
Hello Stateless Init!
Run for the second time:

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloStateful/dist/HelloStateful.jar:$HOME/work/HelloApp/HelloStateless/dist/HelloStateless.jar:. com.bekijkhet.helloclient.HelloStatefulClient
Hello Stateful Not set!
Hello Stateful Initialized!
Hello Stateful Not set!
Hello Stateless Init!
Hello Stateless Init!
Hello Stateless Init!

Notice that everytime you create a new stateful session bean you get a new fresh instance. But when you set it it keeps its state during the client session.

When a stateless session bean is created you always get the same instance (from out of a pool). It looks like the state is kept, but this is server independant and can never been garenteed. When we call the client again after +/- half an hour we get a fresh stateless bean, so it gets cleaned up. This clean up process can happen all the time, even between two calls of the same instance in the same client session.

6 comments:

  1. Hi,
    This is exactly what I've been looking for: an example that would clearly demonstrate the difference between these two types of EJBs _and_ that would be possible to build without any IDE, without unneeded complexities, that is by hand. Thanks!

    ps: I visited this page with Firefox 2 and 3 beta (both under Linux Gutsy), and on none of them worked the 'copy to clipboard' feature, so I had to do some workaround, that that's ok

    ReplyDelete
  2. Thanx man! It's clear example of difference between Session bean types :)

    ReplyDelete
  3. Hi,
    I think stateful seesion bean preserve the state and stateless does not preserve the state between method calls. I am confused after reading articles now. Sorr i am trying to learn J2EE, I may be wrong.

    Thanks

    ReplyDelete
  4. Thanks a lot man. This example along with your comment clarified statements from others.

    ReplyDelete
  5. Thank you, this helped me a lot because in the books the people describe the difference as something like "it mantains the state in business calls and bla bla bla" but somethimes it's hard to understand that, but with a simple example the concept is very clear, thanks!!

    ReplyDelete