Java Tutorial - Java Scipt : Session Bean Tests and Sample Code

Java Tutorial - Java Scipt :

Session Bean Tests and Sample Code


<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE ejb-jar PUBLIC “-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 2.0//EN” “http://java.sun.com/dtd/ejb-jar_2_0.dtd”>
<ejb-jar >
<enterprise-beans>
<session >
<ejb-name>Greeter</ejb-name>
<home>test.interfaces.GreeterHome</home>
<remote>test.interfaces.Greeter</remote>
<local-home>test.interfaces.GreeterLocalHome</local-home>
<local>test.interfaces.GreeterLocal</local>
<ejb-class>test.ejb.GreeterBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

Notice how we specified the files that compose our EJB and declared what type of EJB our Greeter EJB is. We also have declarative information about how the EJB should function—namely that transactions should be managed by the container. There are many options available, and you should consult an EJB reference for all the details.
Next, we need to write the EJB container-specific descriptor file. This declares things that are specific to JBoss such as where to bind our little EJB. This file is named jboss.xml. We’ve kept it as minimal as possible, but there are also many options available here. Please consult the JBoss documentation for more details.
Here are the contents of jboss.xml:

<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE jboss PUBLIC “-//JBoss//DTD JBOSS 3.0//EN”
“http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd”>
<jboss>
<enterprise-beans>
<session>
<ejb-name>Greeter</ejb-name>
<jndi-name>ejb/Greeter</jndi-name>
<local-jndi-name>ejb/GreeterLocal</local-jndi-name>
</session>
</enterprise-beans>
</jboss>

Okay, so now we have our class files and the descriptors. It’s now time to package them together into an EJB .jar file that we can deploy to the EJB container! We’ll be using the command line jar command, but this task is often
handled by your IDE or Ant build script. On Windows the command is:

jar cvf greeter-ejb.jar test\ejb\GreeterBean.class test\interfaces\Greeter.class
test\interfaces\GreeterLocal.class test\interfaces\GreeterHome.class
test\interfaces\GreeterLocalHome.class META-INF\ejb-jar.xml META-INF\jboss.xml

And on Linux the command is:

jar cvf greeter-ejb.jar test/ejb/GreeterBean.class test/interfaces/Greeter.class
test/interfaces/GreeterLocal.class test/interfaces/GreeterHome.class
test/interfaces/GreeterLocalHome.class META-INF/ejb-jar.xml META-INF/jboss.xml

Now, we have our EJB Jar file! Check to make sure that JBoss is up and running.
Once that’s done we can deploy the EJB by simply copying the EJB .jar file into JBoss’s deploy directory, usually the following:

%JBOSS_HOME%%\server\default\deploy

JBoss should pick up the addition within a couple seconds and begin deploying it. Once the deployment is complete, check the JMX console to make sure it’s really deployed. There should now be an entry under the jboss.management.single section that looks something like:

J2EEApplication= ,J2EEServer=Single,j2eeType=EJBModule,name=greeter-ejb.jar

If that’s the case, your EJB is properly deployed and running! Now, we need to test it from the client’s perspective. For that purpose, we’ll be whipping up a simple JSP page that calls on the Greeter EJB. Actually, it won’t be too simple, because we’ll need to create a .war file and include the proper Web application descriptor files to let the EJB container know what we plan on doing. The JSP page uses the session to hold a reference to the Greeter EJB. This
saves us the expense of performing the JNDI lookup each time. In real-world applications, the presentation layer wouldn’t be concerned with these issues and this kind of stuff would be pushed back into the servlet or a stateless session bean facade that coordinates things. We’re just using JSP as a quick-anddirty way to exercise the EJBs.
Here’s the code for index.jsp:

<%@ page
session=”true”
isThreadSafe=”true”
isErrorPage=”false”
import=”javax.naming.*, javax.rmi.*, test.interfaces.*”
%>
<html>
<head>
<title>jsp ejb client</title>
</head>
<body>
<h4>Ejb web-client test</h4>
<p>
It is now <%= new java.util.Date() %>.
</p>
<p>
Exercising the right to vote!
</p>
<p>
<%
try
{
// —- Generate a list of names to choose from. —-
String names[] = { “judy”, “alex”, “eric”, “alice” };
// — Retrieve the reference to our Greeter EJB from the JSP
// — session if possible.
Greeter greeter = (Greeter) session.getAttribute( “greeter” );
if( greeter == null )
{
out.println( “<br> Creating new EJB reference to greeter.” );
Context context = new InitialContext();
GreeterHome home = (GreeterHome)
PortableRemoteObject.narrow( context.lookup( “ejb/Greeter” ),
GreeterHome.class );
greeter = (Greeter)
PortableRemoteObject.narrow( home.create(), Greeter.class );
session.setAttribute( “greeter”, greeter );
}
// —- Exercise the EJB by getting a couple greetings. —-
for( int i=0; i<10; ++i )
{
out.println( “<br>”
+ greeter.sayHello(
names[ (int)( Math.random() * names.length ) ] ) );
}
}
catch( Exception e )
{
out.println( “Caught exception: “
+ e.getMessage() + “ Details: “
+ e );
e.printStackTrace();
}
%>
</p>
</body>
</html>

Almost there! We just have to add a couple of Web-application descriptors. The standard J2EE Web-application descriptor is web.xml. In addition, JBossspecific descriptors are housed in the jboss-web.xml file. Both of these files
reside within the WEB-INF subdirectory. Here’s the code for web.xml:

<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE web-app PUBLIC
“-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
“http://java.sun.com/dtd/web-app_2_3.dtd”>
<web-app >
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<ejb-ref>
<description>Greeter</description>
<ejb-ref-name>Greeter</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>test.interfaces.GreeterHome</home>
<remote>test.interfaces.Greeter</remote>
<ejb-link>Greeter</ejb-link>
</ejb-ref>
</web-app>
And here’s the code for jboss-web.xml:
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE jboss-web PUBLIC
“-//JBoss//DTD Web Application 2.3//EN”
“http://www.jboss.org/j2ee/dtd/jboss-web_3_0.dtd”>
<jboss-web>
<context-root>/ejb_tests</context-root>
<!-- EJB References -->
<ejb-ref>
<ejb-ref-name>Greeter</ejb-ref-name>
<jndi-name>ejb/Greeter</jndi-name>
</ejb-ref>
</jboss-web>

To create the .war file, we just need to jar up index.jsp, the descriptor files, and the interface class files. Create the WEB-INF\classes directory, and copy all the interface files into it. Then jar everything up and copy the .war
file into the JBoss deploy directory.For example, on Windows the commands are:

mkdir WEB-INF\classes
copy test\interfaces\Greeter.class WEB-INF\classes
copy test\interfaces\GreeterLocal.class WEB-INF\classes
copy test\interfaces\GreeterHome.class WEB-INF\classes
copy test\interfaces\GreeterLocalHome.class WEB-INF\classes
jar cvf greeter.war WEB-INF index.jsp
copy greeter.war %JBOSS_HOME%\server\default\deploy

On Linux the commands are:

mkdir WEB-INF/classes
cp test/interfaces/Greeter.class WEB-INF/classes
cp test/interfaces/GreeterLocal.class WEB-INF/classes
cp test/interfaces/GreeterHome.class WEB-INF/classes
cp test/interfaces/GreeterLocalHome.class WEB-INF/classes
jar cvf greeter.war WEB-INF index.jsp
cp greeter.war $JBOSS_HOME/server/default/deploy

Now that we’ve got it running, let’s step back and take a look at what the application does. In the JSP page, we draw a random name and ask the Greeter EJB to greet us. The greeting will also include the name of the last person it greeted. Go ahead and visit the page a couple times. The URL for it is http://localhost: 8080/ejb_tests/.

If you get an error message stating that the Tools.jar file is not found, the most likely culprit is a missing or incorrect JAVA_HOME setting. Be sure to set the JAVA_HOME environment variable to point to the directory where the JDK is installed.

The Greeter EJB basically greets the user based on the name passed in and mentions the last person it has greeted. In a stateless session bean, we are not guaranteed anything regarding the state of our EJB between method calls. You
should avoid keeping stateful information for that reason, even though this restriction is not strictly enforced by the EJB container. Besides, the very notion runs contrary to the spirit of the stateless session bean. One way to see how this state is unreliable is to see what happens when you use two different client sessions. This can be done by using two different computers or by having two browsers (not browser windows). Open up the page and refresh it. Just based on the information displayed by the last browser greeted, it may seem as if state is maintained. However, this is a dangerous  assumption because the EJB container is free to create a pool of stateless session beans and dole them out as it deems fit. If we want the state to be consistent to a client, we need to use a stateful session bean.
It is just a simple matter of modifying a descriptor file to switch the Greeter from a stateless session bean to a stateful session bean. Just edit ejb-jar.xml and replace Stateless with Stateful. Make an updated EJB .jar file and redeploy. That’s all there is to it! Now, if you access the Greeter with multiple clients, you’ll find that it is consistent within the client session—which is how stateful session beans are designed to be! The typical example of the shopping cart or user preferences makes it easy to see the usefulness of this construct.

The stateful session bean is a server-side component. It is only reachable as long as the client retains a reference to it, which is why our JSP page holds the reference within the session. There are many methods and locations where an enterprise application can choose to hold and retain state for a client. Knowing how the stateful session bean works will, hopefully, make it easier to tackle the problem.