Wednesday, November 21, 2007

Stateful and Stateless EJB sample

Wednesday, November 21, 2007 Posted by Andre Broers
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.