http://www.javaworld.com/javaworld/jw-02-2005/jw-0214-springejb_p.html


<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   
      <meta content="Percussion Rhythmyx" name="generator">
      <title>Pro Spring: Spring and EJB - Java World</title>
      
      <script language="JavaScript">
			var topicid = 2; 
		    subtopicid = 8; 
		</script><script>
			function HighlightText(divid){
			var code = document.body.createTextRange();
			code.moveToElementText(document.getElementById('codewrap' + divid));
			code.execCommand("SelectAll");
			code.execCommand("Copy");
			} 
		</script><meta name="TopicID" content="2,4">
      <meta name="SubTopicID" content="8,21">
      <meta name="channels" content="Java World">
      <meta name="description" content="In traditional J2EE applications, Enterprise JavaBeans (EJB) often&#xA;forms the cornerstone of an application's architecture. Although&#xA;Spring provides simpler versions of many of the services provided&#xA;by EJB, such as declarative transaction management and object&#xA;persistence, many applications will continue to be built using EJBs&#xA;for some time. Thankfully, you can still utilize Spring in an&#xA;EJB-based solution, and in this article, an excerpt from Pro Spring (Apress, January 2005),&#xA;authors Rob Harrop and Jan Machacek look at how Spring can simplify&#xA;the creation of EJBs and provide a straightforward, DI-friendly way&#xA;to access EJB resources.">
      <meta name="keywords" content="Java Enterprise Edition,add keywords to help search engines properly categorize the article">
      <meta name="contenttype" content="News">
      <meta name="publicationDate" content="2005-02-14">
      <meta name="author" content="Rob Harrop and Jan Machacek">
      <meta name="publisher" content="JavaWorld.com">
      
      
      
      
      
      
      
      
      
      <meta http-equiv="expires" content="0" />
<meta http-equiv="Pragma" content="no-cache" />



	










  



  




<!-- SSI Error -->


		


<!-- put the # sign in the comment below to go live -->




<style>#reg{BACKGROUND: #ebe7d9;PADDING:5px;}</style>
<script language="javascript">
  var outerref = new String("(none)");
  var nwchannel = 'jw';
  var refresh = 0;
</script>
<base target = "_top">
<script src="/includes/head-scripts.js"></script>

<!-- HBX -->
<script language="javascript1.1">
var _hbEC=0,_hbE=new Array;function _hbEvent(a,b){b=_hbE[_hbEC++]=new Object();b._N=a;b._C=0;return b;}
var hbx=_hbEvent("pv");hbx.vpc="HBX0103u";hbx.gn="a.javaworld.com";
var doctitle = hbxStrip(document.title);
var loc = new String(document.location.href);
loc = hbxStrip(loc);

hbx.acct="DM54120129AB;DM550210NGWB";
hbx.pn="PUT+PAGE+NAME+HERE";
hbx.mlc="CONTENT+CATEGORY";
hbx.pndef="title";
hbx.ctdef="full";
hbx.lvm="300";
hbx.lidt="txl";

hbx.fv="";//FORM VAL MIN
hbx.lt="auto"; //LINK TR
hbx.dlf="n";//Dl FILTER
hbx.dft="n";//Dl FILE NAMING
hbx.elf="n";//EXIT LINK FILTER

hbx.seg="-1";
hbx.ci="";
hbx.hc1="jw_enterprise|";
hbx.hc2=keywords+"|"+doctitle;
hbx.hc3=author+"|"+doctitle;
hbx.hc4=doctitle+"|"+author;
hbx.pec="";//ERROR CODES
</script><script language="javascript1.1" src="/includes/hbx.js"></script>
<!--END HBX -->

<!--
channels: jw
keywords (topics): Java Enterprise Edition
contenttype (tasks): News
site: jw_enterprise
pagename: enterprise
keyval: enterprise
ibsearch: (none)
-->

	 

      <link href="/includes/styles/adstyles.css" rel="stylesheet" type="text/css">
      <link href="/includes/styles/jw-main.css" rel="stylesheet" type="text/css">
   </head>
   <body onload="init()">
      
      <!--stopindex-->
      
      <div id="wrapper">
         <div id="bannerarea">
            <div id="mainbanner">
               



<script> bannersrc = "http://ad.doubleclick.net/adi/idg.us.nwf.jw_enterprise/;pos=top;sz=728x90;ptile=1;type=news;ord=014914?";</script>
<!--stopindex-->
<!-- begin ad tag -->
<NOLAYER>
<IFRAME id="banner" src="http://ad.doubleclick.net/adi/idg.us.nwf.jw_enterprise/;pos=top;sz=728x90;ptile=1;type=news;ord=014914?" width="728" height="90" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no">
<A href="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;abr=!ie;pos=top;sz=728x90;ptile=1;type=news;ord=014914?">
<IMG src="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;abr=!ie;pos=top;sz=728x90;ptile=1;type=news;ord=014914?" border="0" width="728" height="90"></A>
</IFRAME>
</NOLAYER>
<ILAYER id="banner" visibility="hidden" width="728" height="90"></ILAYER>
<!-- end ad tag -->


            </div>
            <div class="separator">
               <!-- xxxxxxxxxxxxxx -->
            </div>
            <div id="masthead">
               <div id="logoarea">
                  <a href="http://www.javaworld.com"><img src="/images/jw-logo.gif" alt="JavaWorld" width="201" height="58" border="0" /></a>
               </div>
                 <div id="searcharea"><form method="get" accept-charset="iso-8859-1" action="http://www.javaworld.com/ifind/java/query.html"><input type=hidden name="qm" value="0" />
<input type=hidden name="st" value="1" />
<input type=hidden name="nh" value="10" />
<input type="hidden" name="col" value="java" />
  <table border="0" cellspacing="0" cellpadding="0">
  <tr valign="top">
    <td><input type="text" name="qt" class="formfield" value="" maxlength="1991"></td>
    <td><input class="submit" name="" type="image" src="/includes/styles/i/but/lw-search-button.gif" alt="Search" value="Go" /></td>
    <td><span><a href="http://www.javaworld.com/ifind/java/query.html?col=java&qs=&qc=&si=0&ql=a&nh=25&lk=1&rf=0">Advanced search</a></span></td>
  </tr>
</table>
  </form>
</div>

            </div>
            <div class="separator">
               <!-- xxxxxxxxxxxxxx -->
            </div>
         </div>
         <!--Start Menu--><script language="javascript" src="/includes/lookup_topic.js" xml:space="preserve"> </script><div id="toolbar"><img height="15" src="/images/jw-logo-tagline.gif" width="125"/><div id="medallion"><!-- begin ad tag -->

<table width="125"  border="0" cellspacing="0" cellpadding="0"><tr><td><SCRIPT LANGUAGE="JavaScript1.1" SRC="http://ad.doubleclick.net/adj/idg.us.nwf.jw_enterprise/;pos=n1;sz=120x90;ptile=2;type=news;ord=014914?" ></SCRIPT></td></tr></table>
<script>
if ((!document.images && navigator.userAgent.indexOf("Mozilla/2.") >= 0)  || navigator.userAgent.indexOf("WebTV")>= 0) {
document.write('<A HREF="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;pos=n1;sz=120x90;ptile=2;type=news;ord=014914?" TARGET="_blank">');
document.write('<IMG SRC="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;pos=n1;sz=120x90;ptile=2;type=news;ord=014914?" WIDTH="120" HEIGHT="90" BORDER="0" ALT="Click Here"></A>');
}
</script>
<NOSCRIPT>
<A HREF="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;pos=n1;sz=120x90;ptile=2;type=news;ord=014914?" TARGET="_blank">
<IMG SRC="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;pos=n1;sz=120x90;ptile=2;type=news;ord=014914?" WIDTH="120" HEIGHT="90" BORDER="0" ALT="alt text">Click Here</A>
</NOSCRIPT>
<!-- end ad tag --><div></div></div><div id="toolbarhome"><ul><li id="hmbar" class=""><a href="/index.html" shape="rect">Home</a></li></ul></div><ul><li class="research"><a href="/topics/index.html" shape="rect">Research Centers</a></li></ul><div id="toolbar_rc"><ul class="botbar"><li id="navbar1" class="nobracket"><a shape="rect" id="linknav1" href="/channel_content/jw-core-index.html" class=""><span id="showplus1" class="toolbar-red">
			+ </span>Java Standard Edition</a><div id="toolbar_rcsubs1"><ul><li id="subnav98" class=""><a shape="rect" href="/channel_content/jw-apis-index.html">APIs</a></li><li id="subnav105" class=""><a shape="rect" href="/channel_content/jw-awt-index.html">AWT / Swing</a></li><li id="subnav108" class=""><a shape="rect" href="/channel_content/jw-patterns-index.html">Design Patterns</a></li><li id="subnav37" class=""><a shape="rect" href="/channel_content/jw-ui-index.html">User Interface Design</a></li><li id="subnav13" class=""><a shape="rect" href="/channel_content/jw-jdbc-index.html">Java Database Connectivity (JDBC)</a></li><li id="subnav103" class=""><a shape="rect" href="/channel_content/jw-jvm-index.html">Java Virtual Machine (JVM)</a></li><li id="subnav65" class=""><a shape="rect" href="/columns/jw-qna-index.html">Java Q&amp;A</a></li><li id="subnav57" class=""><a shape="rect" href="/columns/jw-tips-index.html">Java Tips</a></li></ul></div></li><li id="navbar2" class="nobracket"><a shape="rect" id="linknav2" href="/channel_content/jw-enterprise-index.html" class=""><span id="showplus2" class="toolbar-red">
			+ </span>Java Enterprise Edition</a><div id="toolbar_rcsubs2"><ul><li id="subnav8" class=""><a shape="rect" href="/channel_content/jw-ejbs-index.html">Enterprise JavaBeans (EJBs)</a></li><li id="subnav16" class=""><a shape="rect" href="/channel_content/jw-message-index.html">Java Message Service</a></li><li id="subnav14" class=""><a shape="rect" href="/channel_content/jw-jsp-index.html">JavaServer Pages</a></li><li id="subnav19" class=""><a shape="rect" href="/channel_content/jw-servlets-index.html">Servlets</a></li><li id="subnav9" class=""><a shape="rect" href="/channel_content/jw-webserv-index.html">Web Services and SOAs</a></li><li id="subnav10" class=""><a shape="rect" href="/channel_content/jw-xml-index.html">Java and XML</a></li><li id="subnav30" class=""><a shape="rect" href="/channel_content/jw-design-index.html">Design Patterns</a></li><li id="subnav31" class=""><a shape="rect" href="/channel_content/jw-performance-index.html">Performance Tuning</a></li></ul></div></li><li id="navbar3" class="nobracket"><a shape="rect" id="linknav3" href="/channel_content/jw-micro-index.html" class=""><span id="showplus3" class="toolbar-red">
			+ </span>Java Micro Edition</a><div id="toolbar_rcsubs3"><ul/></div></li><li id="navbar4" class="nobracket"><a shape="rect" id="linknav4" href="/channel_content/jw-applied-index.html" class=""><span id="showplus4" class="toolbar-red">
			+ </span>Development Tools</a><div id="toolbar_rcsubs4"><ul><li id="subnav38" class=""><a shape="rect" href="/channel_content/jw-amt-index.html">Application Management</a></li><li id="subnav41" class=""><a shape="rect" href="/channel_content/jw-dataaccesstools-index.html">Data Access Tools</a></li><li id="subnav44" class=""><a shape="rect" href="/channel_content/jw-gamingtools-index.html">Gaming Tools</a></li><li id="subnav21" class=""><a shape="rect" href="/channel_content/jw-webdev-index.html">Web Development Frameworks</a></li><li id="subnav110" class=""><a shape="rect" href="/channel_content/jw-security-testing-index.html">Security &amp; Testing</a></li><li id="subnav12" class=""><a shape="rect" href="/channel_content/jw-appserv-index.html">Java Application Servers</a></li><li id="subnav48" class=""><a shape="rect" href="/channel_content/jw-profilingtools-index.html">Profiling and Monitoring</a></li><li id="subnav49" class=""><a shape="rect" href="/channel_content/jw-reportingtools-index.html">Reporting</a></li></ul></div></li></ul></div> <!-- use li class=current1 to hightlight the items below-->
    <ul class="botbar">
      <li class="toplevel2"><a href="/resources/site-resources.html">Site Resources</a></li>
      <li id="sr87" class=""><a href="/features/index.html">Featured Tutorials</a></li>
	  <li id="sr89" class=""><a href="/news-reviews/index.html">News &amp; Reviews</a></li>
	  <li id="sr990" class=""><a href="/javaforums/ubbthreads.php?Cat=2&C=2">Forum</a></li>
      <li id="sr991" class=""><a href="/newsletter/">Newsletters</a></li>
      <li id="sr95" class=""><a href="/white-paper/index.html">White Paper Library</a></li>
      <li id="sr199" class=""><a href="/resources/index.html">Web resources</a></li>
      <li id="sr992" class=""><a href="/rss/index.html">RSS Feeds</a></li>
    </ul>
	 <ul class="botbar">
      <li class="toplevel2"><a href="http://javaworld.4jobs.com">Careers</a></li>
    </ul>
    <div class="toolspace">
      <!--3px of space-->
    </div>
    <ul class="botbar">
      <li class="toplevel2"><a href="/partners.html">Partner Sites</a></li>
      <li><a href="http://www.demo.com">Demo.com</a></li>
	  <li><a href="http://www.linuxworld.com">LinuxWorld.com</a></li>
      <li><a href="http://www.networkworld.com">NetworkWorld.com</a></li>  
    </ul>
	<ul><li class="toplevel2"><a href="/info/jw-about-index.html">About Us</a></li>
	</ul>
	<script language="javascript">if (typeof menu_lookup == "function") menu_lookup();</script>
	<br>
	<div id="techwords" style="background-color:#FFFFFF;">
	<h6>sponsored links</h6>
		<a href="http://www.techwords.com/">See your link here.</a>
		<script type="text/javascript">
		adsonar_placementId=1268728;
		adsonar_pid=462761;
		adsonar_ps=1424789;
		adsonar_zw=120;
		adsonar_zh=600;
		adsonar_jv='ads.adsonar.com';
		</script>
		<script language="JavaScript" src="http://js.adsonar.com/js/adsonar.js"></script>
	</div>
	</div>
         <div class="rc" id="contentarea">
            <div id="rcheader">
               <!--startindex-->
               <div id="toptabs">
                  <ul>
                     <li><a href="/channel_content/jw-enterprise-index.html">Java Enterprise Edition</a></li>
                  </ul>
               </div>
               <!--stopindex-->
            </div>
            <div id="idglogin">
               <!-- xxxxxxxxxxxxxx -->
            </div>
            <div id="sectionhome">
               <div id="a-e_col1">
                  <div id="d-e_col2b">
                     <div id="d-e-1">
	<div id="tabs">
		<ul>
		<li class="ts"><a href="javascript:opentab('topstories');" class="ts" id="topstories_a">Top 5 Stories</a></li>
		<li class="saved"><a href="javascript:opentab('savedarticles');" class="saved" id="savedarticles_a">Editor's Choice</a></li>
		</ul>
	</div>
	<div id="topstories">
		 <p><a href="http://www.javaworld.com/javaworld/jw-03-2007/jw-0305-jobs.html">High-impact tech talent in high demand</a><br><a href="http://www.javaworld.com/javaworld/jw-03-2007/jw-0327-ides.html">Reinvigorated Java IDEs change the development landscape</a><br><a href="http://www.javaworld.com/javaworld/jw-03-2007/jw-03-jxpath.html">Java object queries using JXPath</a></p>
<p><b>From the archives:</b></p>
<p><a href="http://www.javaworld.com/javaworld/jw-07-1999/jw-07-toolbox.html">Building user interfaces for object-oriented systems</a><br><a href="http://www.javaworld.com/javaworld/jw-10-2000/jw-1020-ant.html">Automate your build process using Java and Ant</a></p>
	</div>
	<div id="savedarticles">
		 <p><b>More on gird computing:</b></p>
<p><a href="http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-grid.html">A do-it-yourself framework for grid computing</a><br><a href="http://www.javaworld.com/javaworld/jw-08-2004/jw-0802-grid.html">Achieve bottleneck-free grid applications</a></p>
	</div>
</div>

<script type="text/javascript">
divnames = new Array('topstories', 'savedarticles'); <!--,'topstories'-->
opentab("topstories");

function opentab(divname) {	;
	if(document.getElementById(divname)) {
		for (i=0;i < 2;i++) {	<!-- 2-->
			var aname = divnames[i] + '_a';		
			if (divnames[i] == divname)	{	
				tab=divname;		    
				document.getElementById(divname).style.display='block';
				document.getElementById(aname).parentNode.id = "current";	
			}
			else {
				document.getElementById(divnames[i]).style.display='none';
				document.getElementById(aname).parentNode.id = "none";
			}
		}
	}
}
</script>


                     <div class="imu">
                        <!--stopindex-->







<script language="JavaScript">
<!--
var imuvar;
myImage = new Image();
myImagef = new Image();
function resize(){
	//return; //just comment this out to activate the resize function
	imuvar = document.getElementById("imu");
	myImage.src = "http://www.javaworld.com/ads/halfpage.jsp?get=true&ord=014914";
	setTimeout("getSize()",300);
	setTimeout("finalSize()",1200);
}

function finalSize(){
	if (imuvar.height < 600) {
		imuvar = document.getElementById("imu");
		myImagef.src = "http://www.javaworld.com/ads/halfpage.jsp?get=true&ord=1014914";
		getSizef();
	}
}

function getSizef() {
    if (myImagef.height == 0) setTimeout("getSizef()",200);	
	if (myImagef.height == 600) imuvar.height=600;
}

function getSize() {
    if (myImage.height == 0) setTimeout("getSize()",200);	
	if (myImage.height == 600) imuvar.height=600;
}
//-->
</script>
  
  <NOLAYER>
  <IFRAME id="imu" src="http://ad.doubleclick.net/adi/idg.us.nwf.jw_enterprise/;pos=imu;sz=336x280;ptile=3;type=news;ord=014914?" onload="resize()" width="336" height="280" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no">
  <A href="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;abr=!ie;pos=imu;sz=336x280;ptile=3;type=news;ord=014914?">
  <IMG src="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;abr=!ie;pos=imu;sz=336x280;ptile=3;type=news;ord=014914?" border="0" width="336" height="280"></A>
  </IFRAME>
  </NOLAYER>
  <ILAYER id="imu" visibility="hidden" width="336" height="280"></ILAYER>
	<script> imusrc = "http://ad.doubleclick.net/adi/idg.us.nwf.jw_enterprise/;pos=imu;sz=336x280;ptile=3;type=news;ord=";</script>

                     </div>
                     <!--Featured White Papers--><div id="de3"><h2>Featured White Papers</h2><ul><li><a href="http://adserver.fattail.com/redir/redirect.asp?CID=216050" target="_blank" onclick="" title=" Apache Tomcat and Terracotta Session Clustering Comparison and Real-world Benchmarks"> Apache Tomcat and Terracotta Session Clustering Comparison and Real-world Benchmarks</a></li><li><a href="http://adserver.fattail.com/redir/redirect.asp?CID=216053" target="_blank" onclick="" title="Jaxcent:  AJAX in Java.  No JavaScript.">Jaxcent:  AJAX in Java.  No JavaScript.</a></li><li><a href="http://adserver.fattail.com/redir/redirect.asp?CID=214803" target="_blank" onclick="" title="A Dashboard Data Methodology: Five Key Steps to Properly Organize Data for a Dashboard Project">A Dashboard Data Methodology: Five Key Steps to Properly Organize Data for a Dashboard Project</a></li><li><a href="http://adserver.fattail.com/redir/redirect.asp?CID=214281" target="_blank" onclick="" title="Enterprise AJAX - Transcend the Hype">Enterprise AJAX - Transcend the Hype</a></li><li><a href="http://adserver.fattail.com/redir/redirect.asp?CID=212416" target="_blank" onclick="" title="An Introduction to Open Terracotta">An Introduction to Open Terracotta</a></li></ul></div>
                             <!-- nl signup start-->
		<form action="http://www.subscribenw.com/nl/Signup.do" id="Form2" method="post" name="form" onSubmit="openNewWindow()" target="new_window">
          <div id="newsletter">
            <h5>Newsletter sign-up</h5>
			<p class="nl">Sign up for our technology specific newsletters.</p>
            <table width="300" border="0" cellpadding="0" cellspacing="0">
              <tr>
                <td width="27" valign="top" class="bgleft"><input name="NL70" type="checkbox" id="NL70"/></td>
                <td width="265" class="bgright"><a href="javascript:openWindow('http://www.subscribenw.com/nl/popup.jsp?id=70',500,300);">Enterprise Java</a></td>
              </tr>
			  <tr><td colspan="2"><a href="http://www.subscribenw.com/nl/signup.jsp?keycode=JW07">View all newsletters</a></td></tr>
		    </table>
            <hr color="#CCCCCC" noshade="noshade" size="1"/>
            <strong>Email Address:</strong>
			<input id="keycode" name="keycode" type="hidden" value="NLmsu08"/>
			<input id="call" name="call" type="hidden" value="instant"/>
			<input name="pid" type="hidden" value="121"/>
			<input name="email" size="14" type="text"/>
            <input alt="Submit" name="Button" type="submit" value="Subscribe" id="Submit1"/>
          </div>
        </form>

                     <!--include virtual="/includes/topic/enterprise-nl-signup.html"-->
                     
<div id="de5">
<!-- begin ad tag -->
<SCRIPT LANGUAGE="JavaScript1.1" SRC="http://ad.doubleclick.net/adj/idg.us.nwf.jw_enterprise/;pos=de5;sz=336x175;tile=5;ord=014914?" ></SCRIPT>
<script>
if ((!document.images && navigator.userAgent.indexOf("Mozilla/2.") >= 0)  || navigator.userAgent.indexOf("WebTV")>= 0) {
document.write('<A HREF="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;pos=de5;sz=336x175;tile=5;ord=014914?" TARGET="_blank">');
document.write('<IMG SRC="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;pos=de5;sz=336x175;tile=5;ord=014914?" WIDTH="336" HEIGHT="175" BORDER="0" ALT="Click Here"></A>');
}
</script>
<NOSCRIPT>
<A HREF="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;pos=de5;sz=336x175;tile=5;ord=014914?" TARGET="_blank">
<IMG SRC="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;pos=de5;sz=336x175;tile=5;ord=014914?" WIDTH="336" HEIGHT="175" BORDER="0" ALT="alt text">Click Here</A>
</NOSCRIPT>
<!-- end ad tag -->
</div>

                  </div>
                  <div class="breadcr"><a href="/index.html">JavaWorld.com</a>
                     &gt; <a href="/channel_content/jw-enterprise-index.html">Java Enterprise Edition</a> &gt;</div>
                  <div>
                     
                     <!--HEADLINE GOES HERE-->
                     
                     <!--startindex-->
                     <a id="top" name="top"></a><h1>Pro Spring: Spring and EJB</h1>
                     <H3>Learn how to use Spring with EJB applictions</H3>
                     <p class="byline">By&nbsp;Rob Harrop&nbsp;and&nbsp;Jan Machacek,&nbsp;JavaWorld.com,&nbsp;02/14/05</p>
                     
                     <!-- CONTENT GOES HERE-->
                     
                     <p class="first">With the advent of Spring, developers now have, for the first time, a truly lightweight alternative to EJB (Enterprise JavaBeans).
                        Using Spring, you can take advantage of many of the features offered by EJB, such as declarative transaction management, object
                        pooling, and simple ORM (object role modeling) functionality. That said, we anticipate that EJB will continue to be used for
                        application development for the foreseeable future. Although we do not look at reasons for or against using EJB in this book,
                        our experience with Spring has been excellent, and we recommend that you use it instead of EJB whenever you can. For a more
                        complete discussion of the pros and cons of both Spring and EJB, read <em><a href="#resources">Expert One-on-One J2EE without EJB</a></em> by Rod Johnson and Juergen Hoeller (Wrox, 2004). What we <strong>are</strong> going to focus on in this article is how you can continue to use Spring even though you are building your application using
                        EJB.
                     </p>
                     <h3>EJB support in Spring</h3>
                     <p>EJB support in Spring can be loosely grouped into two categories: access and implementation. The access support classes in
                        Spring make it easier for you to access EJB resources. In this section, we look at how Spring extends the basic JNDI (Java
                        Naming and Directory Interface) support framework to ease EJB access and utilizes AOP (aspect-oriented programming) support
                        to provide proxy-based access to EJB resources.
                     </p>
                     <p>The EJB implementation support in Spring provides abstract base classes that make it simpler for you to create three types
                        of EJBs: stateless session beans, stateful session beans, and message-driven beans. The basic premise behind these base classes
                        is not so much to ease the burden of creating an EJB, but to enable you to access Spring-managed resources easily from within
                        your beans and, more importantly, to aid you in factoring your business logic out of the EJB implementation and into a POJO
                        (plain old Java object) used by the EJB. Don't worry if this sounds a little unclear at this point; we discuss this in detail
                        in the next section alongside two examples that should make this crystal clear.
                     </p>
                     <p>We will build a simple Web application that uses two EJB services. The first, a stateless session bean, implements the <code>EchoService</code> business interface and provides simple echoing capabilities. The second, a stateful session bean, implements the <code>CounterService</code> business interface and provides stateful services for counting.
                     </p>
                     <p>These are trivial examples, but they help to demonstrate the recommended approach to building EJBs with Spring as well as
                        different components involved in Spring's EJB support. We do not go into great detail about the EJB spec itself, other than
                        to discuss the various deployment descriptors that make up our sample. We do, however, peek inside the implementation of Spring's
                        EJB support at the various components and how they affect your application. In particular, we look at how Spring locates the
                        <code>ApplicationContext</code> for your EJBs and how JNDI resources are located using the JNDI infrastructure.
                     </p>
                     <p>You may have noticed that we mentioned that Spring supports three kinds of EJB, but we are only going to be implementing two
                        types -- stateless and stateful. The message-driven bean support classes follow a similar pattern to those for stateless and
                        stateful session beans.
                     </p>
                     <h3>Building EJBs with Spring</h3>
                     <p>Spring provides three abstract classes to serve as base classes for your EJB bean classes: <code>AbstractStatelessSessionBean</code>, <code>AbstractStatefulSessionBean</code>, and <code>AbstractMessageDrivenBean</code>. When building an EJB using Spring, you still have to provide all the different interfaces and the home class, but when implementing
                        your bean class, you derive from the appropriate Spring base class. The base classes provided by Spring allow your EJBs to
                        access a Spring <code>ApplicationContext</code> and thus allow them to access resources that are managed by Spring.
                     </p>
                     <p>Before we jump into the details of building our <code>EchoService</code> and <code>CounterService</code> beans using Spring, we are going to look at <strong>how</strong> Spring goes about locating an <code>ApplicationContext</code> for your EJBs and the recommended approach for building an EJB when you are using Spring.
                     </p>
                     <h4>The Spring EJB class hierarchy</h4>
                     <p>Spring provides a well-defined class hierarchy for the EJB support classes, as shown in Figure 1.</p>
                     <center>
                        <p><a alt="Figure 1. Spring EJB support classes. Click on thumbnail to view full-sized image." href="images/jw-0214-springejb1.jpg" target="new_window"><img alt="" height="265" src="images/jw-0214-springejb1-thumb.jpg" width="350"></a></p>
                        <p><strong>Figure 1. Spring EJB support classes. Click on thumbnail to view full-sized image.</strong></p>
                     </center>
                     <p>As you can see, the central base class, <code>AbstractEnterpriseBean</code>, exposes the <code>beanFactoryLocator</code> property to allow subclasses access to the <code>BeanFactoryLocator</code> instance being used. The <code>BeanFactoryLocator</code> interface is discussed in more detail in the next section, along with the <code>loadBeanFactory()</code> and <code>unloadBeanFactory()</code> methods. Notice that the <code>AbstractStatelessSessionBean</code> class has already implemented the <code>ejbCreate()</code>, <code>ejbActivate()</code>, and <code>ejbPassivate()</code> methods, whereas <code>AbstractStatefulSessionBean</code> has not. Spring has special requirements regarding bean passivation that we discuss in more detail later, in the section
                        entitled "Building a Stateful Session Bean."
                     </p>
                     <h4>The BeanFactoryLocator interface</h4>
                     <p>One of the key features offered by the base EJB classes in Spring is the ability to access an <code>ApplicationContext</code> from which you can load Spring-managed resources. This functionality is not provided by the base classes themselves; rather,
                        it is delegated to an implementation of the <code>BeanFactoryLocator</code> interface, like the one shown in Listing 1.
                     </p>
                     <p><strong>Listing 1. The BeanFactoryLocator Interface</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(50);"></div>
                     <div id="codewrap">
                        <div id="codewrap50"><pre> <code>public interface BeanFactoryLocator {<br><br>   BeanFactoryReference useBeanFactory(String factoryKey) throws BeansException;<br><br>}</code>
</pre></div>
                     </div><br><br><p>A <code>BeanFactoryLocator</code> is used in circumstances when Spring has no control over the creation of a resource and thus cannot automatically configure
                        it. In these circumstances, a <code>BeanFactoryLocator</code> allows a resource to locate the <code>BeanFactory</code> itself in an externally configurable way. Of course, in such cases, the resource can simply mandate where the <code>BeanFactory</code> configuration must be, but that means that you, as the application developer, have no control over the application. By using
                        <code>BeanFactoryLocator</code>, you can fully control how your EJBs locate the <code>BeanFactory</code> or <code>ApplicationContext</code> they use for configuration.
                     </p>
                     <p>Notice that the <code>BeanFactoryLocator</code> doesn't return a <code>BeanFactory</code> instance directly; instead it returns a <code>BeanFactoryReference</code>. A <code>BeanFactoryReference</code> is a lightweight wrapper around a <code>BeanFactory</code> or <code>ApplicationContext</code> that allows the resource using the <code>BeanFactory</code> to release its reference to the <code>BeanFactory</code> gracefully. The actual implementation of this interface is specific to both the <code>BeanFactoryLocator</code> implementation and the <code>BeanFactory</code> or <code>ApplicationContext</code> interface. We investigate this functionality a little more in Listing 13, when we look at stateful session beans that use
                        their ability to release a <code>BeanFactoryReference</code> to enable bean passivation.
                     </p>
                     <p>By default, all of the base EJB classes use the <code>ContextJndiBeanFactoryLocator</code> implementation of <code>BeanFactoryLocator</code>. Essentially, this class looks in a given JNDI location for a comma-separated list of configuration filenames and creates
                        an instance of <code>ClassPathXmlApplicationContext</code> using these configuration files. You can provide your own implementation of <code>BeanFactoryLocator</code> by setting the <code>beanFactoryLocator</code> property that is exposed by all three base EJB classes via the <code>AbstractEnterpriseBean</code> class. However, if you do so, be aware that each instance of your bean has its own instance of <code>ContextJndiBeanFactoryLocator</code>, and likewise, each instance of <code>ContextJndiBeanFactoryLocator</code> has its own instance of <code>ClassPathXmlApplicationContext</code>.
                     </p>
                     <p>Although all the <code>ApplicationContext</code> instances created for your EJB instances are identically configured, the beans are not identical. Consider a Spring configuration
                        that defines the <code>echoService</code> bean the <code>EchoServiceEJB</code> will use. If your application server creates 100 instances of your EJB, then 100 instances of <code>ContextJndiBeanFactoryLocator</code> are created, along with 100 instances of <code>ClassPathXmlApplicationContext</code> and 100 instances of the <code>echoService</code> bean.
                     </p>
                     <p>If this behavior is undesirable for your application, then Spring provides the <code>SingletonBeanFactoryLocator</code> and <code>ContextSingletonBeanFactoryLocator</code> classes that load singleton instances of <code>BeanFactory</code> and <code>ApplicationContext</code>, respectively. For more information, see the Javadoc for these classes.
                     </p>
                     <h4>The Spring approach to EJB</h4>
                     <p>One of the biggest drawbacks of EJB is that it is very difficult to test EJB components separately from the EJB container,
                        which makes unit testing EJB-implemented business logic a feat only attempted by the particularly masochistic. However, a
                        workaround to this problem has been around in the Java world for a long while; it involves implementing your business logic
                        in a POJO that implements the same business interface as your EJB bean class; you can then have the bean class delegate to
                        the POJO. Using Spring makes this implementation much simpler and much more flexible because you don't have to embed any logic
                        inside the EJB as to how the POJO implementation is located and created. Figure 2 shows how we employ this approach when building
                        the <code>EchoService</code> EJB.
                     </p>
                     <center>
                        <p><img alt="" height="396" src="images/jw-0214-springejb2.jpg" width="401"></p>
                        <p><strong>Figure 2. Using a POJO implementation for an EJB</strong></p>
                     </center>
                     <p>Here, you can see that, as expected, the bean class, <code>EchoServiceEJB</code>, implements the <code>EchoService</code> interface, but also notice that <code>EchoServiceEJB</code> has a dependency on the <code>EchoService</code> interface and a private field of type <code>EchoService</code>.
                     </p>
                     <h4>Building a stateless session bean</h4>
                     <p>A stateless session bean is the easiest EJB to build with Spring; this is because it requires no special handling whatsoever
                        and all the <code>ejbXXX()</code> methods are implemented by the <code>AbstractStatelessSessionBean</code> class.
                     </p>
                     <p>We start by creating the service interface, as shown in Listing 2.</p>
                     <p><strong>Listing 2. The EchoService Interface</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(122);"></div>
                     <div id="codewrap">
                        <div id="codewrap122"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>public interface EchoService {<br><br>   public String echo(String message);
}</code>
</pre></div>
                     </div><br><br><p>Notice that the service interface is not EJB-specific, and indeed, it is not required when implementing the EJB. The traditional
                        approach to EJB development is to define business methods in the EJB-specific local and remote interfaces. In this approach,
                        the business methods are defined in a standard Java interface, and the local and remote bean interfaces extend this standard
                        interface. This service interface provides a standard interface not only for the local and remote interfaces to extend, but
                        it also provides a common interface that both the EJB bean class and the POJO implementation class can implement. Although
                        we recommend that your EJB bean class <em>does not</em> implement either the local or remote interface, there is no problem with the EJB bean implementing the service interface.
                        By having all the components that make up the EJB share a common interface, it is easier to ensure that your local interface
                        defines the methods you intend it to, that your bean class implements the methods expected by the local interface, and that
                        the POJO implementation implements the methods required by the EJB bean class.
                     </p>
                     <p>The next step is to create the bean interface. In this example, we do not use the EJB in a remote container, so we stick to
                        a local interface, as shown in Listing 3.
                     </p>
                     <p><strong>Listing 3. The local interface for the EchoService EJB</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(135);"></div>
                     <div id="codewrap">
                        <div id="codewrap135"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import javax.ejb.EJBLocalObject;<br><br>public interface EchoServiceLocal extends EchoService, EJBLocalObject {<br><br>}</code>
</pre></div>
                     </div><br><br><p>Notice that, as we discussed earlier, no business methods are defined in this interface. Instead, the <code>EchoServiceLocal</code> interface extends the service interface, <code>EchoService</code>.
                     </p>
                     <p>Next, we need to create the EJB home interface. For this example, we are not going to be invoking the EJB remotely, so we
                        stick to a simple local home interface as shown in Listing 4.
                     </p>
                     <p><strong>Listing 4. Local home interface for EchoService EJB</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(151);"></div>
                     <div id="codewrap">
                        <div id="codewrap151"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;<br><br>public interface EchoServiceHome extends EJBLocalHome {<br><br>   public EchoServiceLocal create() throws CreateException;
}</code>
</pre></div>
                     </div><br><br><p>That takes care of most of the boilerplate code required by the EJB specification.</p>
                     <p>When you are building an EJB using a traditional architecture, the next step is to create the bean class. However, we are
                        going to factor the implementation of the <code>EchoService</code> into a POJO and have the EJB bean class delegate to this POJO implementation. Listing 5 shows the POJO implementation of
                        the <code>EchoService</code> interface.
                     </p>
                     <p><strong>Listing 5. POJO Implementation of EchoService</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(167);"></div>
                     <div id="codewrap">
                        <div id="codewrap167"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>public class EchoServiceImpl implements EchoService {<br><br>   public String echo(String message) {
      return message;<br><br>   }
}</code>
</pre></div>
                     </div><br><br><p>Here, all of the implementations of <code>EchoService</code> are contained in a POJO that you can easily test outside of the EJB container (Not that this implementation needs much testing!).
                     </p>
                     <p>The final step in the implementation of the <code>EchoService</code> EJB is to create the bean class itself. This is where Spring comes into the equation. With the actual implementation of the
                        <code>EchoService</code> interface contained in <code>EchoServiceImpl</code>, we can simply choose to create an instance of this instance <code>EchoServiceEJB</code> and be done with it.
                     </p>
                     <p>However, what happens if we want to change the implementation? We need to recompile and redeploy the EJB. By using Spring,
                        we can load the implementation class and any dependencies, from the <code>ApplicationContext</code>. This means that you can take full advantage of all of Spring's features for the actual implementation class, including DI,
                        AOP, and external configuration support. Listing 6 shows the implementation of the <code>EchoService</code> bean class.
                     </p>
                     <p><strong>Listing 6. The EchoServiceEJB class</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(189);"></div>
                     <div id="codewrap">
                        <div id="codewrap189"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import javax.ejb.CreateException;<br><br>import org.springframework.ejb.support.AbstractStatelessSessionBean;<br><br>public class EchoServiceEJB extends AbstractStatelessSessionBean implements EchoService {
   private static final String BEAN_NAME = "echoService";<br><br>   private EchoService service;<br><br>   public String echo(String message) {
      return service.echo(message);
   }<br><br>   protected void onEjbCreate() throws CreateException {
      service = (EchoService) getBeanFactory().getBean(BEAN_NAME);
   }
}</code>
</pre></div>
                     </div><br><br><p>There are a few interesting points to note in this code. First, you should notice that <code>EchoServiceEJB</code> extends the Spring base class <code>AbstractStatelessSessionBean</code> and implements the <code>EchoService</code> interface. Second, all the methods on the <code>EchoService</code> interface are delegated to the wrapped implementation of <code>EchoService</code>. Third, this bean has no <code>ejbXXX()</code> methods&#8212;these are all implemented in <code>AbstractStatelessSessionBean</code>. And finally, notice the <code>onEjbCreate()</code> method. This is a hook method <code>AbstractStatelessSessionBean</code> provides, and it is called during <code>ejbCreate()</code>. This method is perfect for obtaining any Spring-managed resources the EJB bean needs, in particular, the actual implementation
                        of the service interface. As you can see, we retrieved the <code>echoService</code> bean from Spring and stored it in the <code>service</code> field. This bean is the implementation of <code>EchoService</code> to which the <code>EchoServiceEJB</code> delegates.
                     </p>
                     <p>Remember from Figure 1 that the <code>getBeanFactory()</code> method is declared on the <code>AbstractEnterpriseBean</code> class that forms the base of all Spring EJB implementation support classes. By default, the <code>AbstractEnterpriseBean</code> class uses an instance of <code>ContextJndiBeanFactoryLocator</code> to locate and load an <code>ApplicationContext</code> to return from <code>getBeanFactory()</code>. <code>ContextJndiBeanFactoryLocator</code> works by looking in a particular JNDI location for a list of file names from which to load the <code>ApplicationContext</code> configuration. We can specify this list in the deployment descriptor for the EJB as shown in Listing 7.
                     </p>
                     <p><strong>Listing 7. Configuring ContextJndiBeanFactoryLocator in deployment descriptor</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(231);"></div>
                     <div id="codewrap">
                        <div id="codewrap231"><pre> <code>&lt;session&gt;
   &lt;description&gt;Echo Service Bean&lt;/description&gt;
   &lt;ejb-name&gt;EchoServiceEJB&lt;/ejb-name&gt;
   &lt;local-home&gt;com.apress.prospring.ch13.ejb.EchoServiceHome&lt;/local-home&gt;
   &lt;local&gt;com.apress.prospring.ch13.ejb.EchoServiceLocal&lt;/local&gt;
   &lt;ejb-class&gt;com.apress.prospring.ch13.ejb.EchoServiceEJB&lt;/ejb-class&gt;
   &lt;session-type&gt;Stateless&lt;/session-type&gt;
   &lt;transaction-type&gt;Container&lt;/transaction-type&gt;
   &lt;env-entry&gt;
      &lt;env-entry-name&gt;ejb/BeanFactoryPath&lt;/env-entry-name&gt;
      &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
      &lt;env-entry-value&gt;applicationContext.xml&lt;/env-entry-value&gt;
   &lt;/env-entry&gt;
&lt;/session&gt;</code>
</pre></div>
                     </div><br><br><p>The important part in this deployment descriptor is the <code>&lt;env-entry&gt;</code> tag that sets the value of the <code>ejb/BeanFactoryPath</code> JNDI location to <code>applicationContext.xml</code>. The JNDI path <code>ejb/BeanFactoryPath</code> is the default location where <code>ContextJndiBeanFactoryLocator</code> looks for the configuration file path. The configuration in Listing 7 is essentially telling the instance of <code>ContextJndiBeanFactoryLocator</code> associated with the <code>EchoServiceEJB</code> to create an <code>ApplicationContext</code> configured using the details in the <code>applicationContext.xml</code> file.
                     </p>
                     <p>An important point to note is that this configuration file is specific to the EJB and is separate from any <code>applicationContext.xml</code> file you may have for the main application. When we package up the application, we place the <code>applicationContext.xml</code> file specific to the EJBs in the EJB JAR, and then we have the <code>applicationContext.xml</code> file for the Web application in the war file. To finish up with the deployment of the <code>EchoServiceEJB</code>, we also need the JBoss-specific deployment descriptor for the bean. This is shown in Listing 8.
                     </p>
                     <p><strong>Listing 8. JBoss deployment descriptor</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(252);"></div>
                     <div id="codewrap">
                        <div id="codewrap252"><pre> <code>&lt;jboss&gt;
   &lt;enterprise-beans&gt;
      &lt;session&gt;
         &lt;ejb-name&gt;EchoServiceEJB&lt;/ejb-name&gt;
         &lt;local-jndi-name&gt;ejb/echoService&lt;/local-jndi-name&gt;
      &lt;/session&gt;
   &lt;/enterprise-beans&gt;
&lt;/jboss&gt;</code>
</pre></div>
                     </div><br><br><p>The important part in this deployment descriptor is the <code>&lt;local-jndi-name&gt;</code> tag, which tells JBoss the JNDI name to which to bind the EJB home. In this case, we are able to locate an instance of <code>EchoServiceHome</code> under <code>ejb/echoService</code>.
                     </p>
                     <p>That's all for the stateless session bean. As you can see, the implementation steps aren't vastly different from the traditional
                        approach to EJB implementation. However, with the approach taken here, you gain the ability to test your business logic easily
                        and without any dependency on the EJB container. By using Spring, we have made the POJO-based implementation approach much
                        more flexible, and we are easily able to avoid coupling the EJB bean to a particular POJO implementation.
                     </p>
                     <h4>Building a stateful session bean</h4>
                     <p>Building a stateful session bean is slightly more complex than building a stateless session bean because you now have to consider
                        what happens to the <code>ApplicationContext</code> when the bean is passivated. Recall from Figure 1 that <code>AbstractStatefulSessionBean</code> does not implement <code>ejbCreate()</code>, <code>ejbActivate()</code>, and <code>ejbPassivate()</code>. The reason for this is that none of the default <code>BeanFactory</code> and <code>ApplicationContext</code> implementations Spring provides is serializable, and as a result, none can be passivated along with your stateful session
                        bean.
                     </p>
                     <p>To get around this, you have two options. The simplest option is to implement <code>ejbActivate()</code> and <code>ejbPassivate()</code> to load and unload the <code>ApplicationContext</code> as appropriate, which allows the bean to be passivated without storing the <code>ApplicationContext</code> and reconstructing the <code>ApplicationContext</code> when the bean is activated again. The second option is to provide your own implementation of <code>BeanFactoryLocator</code> that creates a <code>BeanFactory</code> or <code>ApplicationContext</code> that <em>is</em> serializable. When you use the first approach, be aware that when you use the <code>ContextJndiBeanFactoryLocator</code>, bean activation results in the <code>ApplicationContext</code> being loaded from scratch. If this is unacceptable overhead for your application, you can swap <code>ContextJndiBeanFactoryLocator</code> for <code>ContextSingletonBeanFactoryLocator</code>, as discussed earlier.
                     </p>
                     <p>As before, to start building the bean, we start with the service interface, shown here in Listing 9.</p>
                     <p><strong>Listing 9. The CounterService interface</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(287);"></div>
                     <div id="codewrap">
                        <div id="codewrap287"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>public interface CounterService {<br><br>   public int increment();<br><br>   public int decrement();
}</code>
</pre></div>
                     </div><br><br><p>Again, we created a basic service interface that will be implemented by the local interface, the bean class, and the implementation
                        class. The next step is to create the local interface, shown in Listing 10.
                     </p>
                     <p><strong>Listing 10. Local interface for CounterService</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(300);"></div>
                     <div id="codewrap">
                        <div id="codewrap300"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import javax.ejb.EJBLocalObject;<br><br>public interface CounterServiceLocal extends CounterService, EJBLocalObject {<br><br>}</code>
</pre></div>
                     </div><br><br><p>Again, the local interface itself contains no method definitions, and all the business methods are inherited from the <code>CounterService</code> interface. Next up, we need to create the home interface, as shown in Listing 11.
                     </p>
                     <p><strong>Listing 11. The local home interface for CounterService</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(314);"></div>
                     <div id="codewrap">
                        <div id="codewrap314"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;<br><br>public interface CounterServiceHome extends EJBLocalHome {<br><br>   public CounterServiceLocal create() throws CreateException;
}</code>
</pre></div>
                     </div><br><br><p>Again, there is nothing special about this implementation; it is just the standard EJB approach.</p>
                     <p>The fourth component required for the <code>CounterService</code> EJB is the POJO implementation. This implementation is stateful and is marked as <code>Serializable</code>, so it can be passivated along with the <code>CounterServiceEJB</code>. Listing 12 shows the <code>CounterServiceImpl</code> class.
                     </p>
                     <p><strong>Listing 12. Basic CounterService implementation</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(332);"></div>
                     <div id="codewrap">
                        <div id="codewrap332"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import java.io.Serializable;<br><br>public class CounterServiceImpl implements CounterService, Serializable {
   private int count = 0;<br><br>   public int increment() {
      return ++count;
   }<br><br>public int decrement() {
      return --count;
   }
}</code>
</pre></div>
                     </div><br><br><p>Thus far, the implementation of the stateful session bean has been similar to the implementation of the stateless session
                        bean. However, there are notable differences when implementing the bean class. Listing 13 shows the bean class for the <code>CounterServiceEJB</code>.
                     </p>
                     <p><strong>Listing 13. The CounterServiceEJB class</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(348);"></div>
                     <div id="codewrap">
                        <div id="codewrap348"><pre> <code>package com.apress.prospring.ch13.ejb;<br><br>import java.rmi.RemoteException;<br><br>import javax.ejb.CreateException;
import javax.ejb.EJBException;<br><br>import org.springframework.ejb.support.AbstractStatefulSessionBean;<br><br>public class CounterServiceEJB extends AbstractStatefulSessionBean implements CounterService {<br><br>   private CounterService service;<br><br>   public int increment() {
      return service.increment();
   }<br><br>   public int decrement() {
      return service.decrement();
   }<br><br>   public void ejbCreate() throws CreateException {
      load();
      service = (CounterService) getBeanFactory().getBean("counterService");
   }<br><br>   public void ejbActivate() throws EJBException, RemoteException {
      load();
      service = (CounterService) getBeanFactory().getBean("counterService");
   }<br><br>   public void ejbPassivate() throws EJBException, RemoteException {
      unload();
}<br><br>   private void load() {
      loadBeanFactory();
   }<br><br>   private void unload() {
      unloadBeanFactory();
      setBeanFactoryLocator(null);
   }
}</code>
</pre></div>
                     </div><br><br><p>The first part of the bean class implementation is similar to that of the <code>EchoServiceEJB</code> that we created earlier. However, the noticeable differences here are in the <code>ejbCreate()</code>, <code>ejbActivate()</code>, and <code>ejbPassivate()</code> methods. In <code>ejbCreate()</code>, we invoke the <code>load()</code> method, which in turn invokes <code>loadBeanFactory()</code> on <code>AbtstractEnterpriseBean</code>. This causes the <code>BeanFactoryLocator</code> implementation to load the <code>BeanFactory</code> and makes it available via a call to <code>getBeanFactory()</code>. Finally the <code>ejbCreate()</code> method uses the <code>BeanFactory</code> to access the <code>counterService</code> bean and stores it in the <code>service</code> field.
                     </p>
                     <p>The bean is now configured for use and will continue to function happily until the container chooses to passivate it. When
                        this happens, the <code>ejbPassivate()</code> method is invoked and, in turn, the <code>unload()</code> method. The first step <code>unload()</code> takes is to invoke <code>unloadBeanFactory()</code>, which clears out the <code>ApplicationContext</code> loaded by the <code>ContextJndiBeanFactoryLocator</code> and sets the reference to <code>null</code>. As we mentioned earlier, the reason for this is that <code>ClassPathXmlApplicationContext</code> (the <code>ApplicationContext</code> implementation used by <code>ContextJndiBeanFactoryLocator</code>) is not serializable, and, as a result, it cannot be passivated along with the bean. Finally, <code>unload()</code> removes all references to the <code>BeanFactoryLocator</code> implementation because, like <code>ClassPathXmlApplicationContext</code>, <code>ContextJndiBeanFactoryLocator</code> is not serializable.
                     </p>
                     <p>When the container is ready to reactivate a bean after passivation, it invokes <code>ejbActivate()</code> on the bean to let the bean know it can reestablish any state that could not be passivated. In this case, we simply invoke
                        <code>load()</code> again to reload the <code>ApplicationContext</code>. Note that if you are using a custom <code>BeanFactoryLocator</code> implementation, then you need to reinstantiate it in <code>ejbActivate()</code> as well. Once the <code>ApplicationContext</code> is reloaded, we reload the <code>counterService</code> bean from the <code>ApplicationContext</code>.
                     </p>
                     <p>You may well be wondering why we bother to reload the <code>ApplicationContext</code> in <code>ejbCreate()</code>. Given that the <code>CounterServiceImpl</code> class is serializable, it will be passivated along with the bean, so all we really need to do is close the <code>BeanFactory</code> once we obtain the <code>counterService</code> bean. However, remember that you can configure <em>any</em> <code>CounterService</code> implementation in the <code>ApplicationContext</code>, including one that is not serializable. If you can guarantee that all implementations are serializable, then you can opt
                        for this approach, perhaps supplementing it with a check in <code>ejbCreate()</code> to ensure that the implementation is actually serializable. Where you cannot guarantee that the implementation is serializable,
                        you have to assume that it is not; therefore, you have to unload the <code>BeanFactory</code> at passivation and reload it on activation.
                     </p>
                     <p>As with the stateless session bean, we need to define the location of the configuration for the <code>ApplicationContext</code> in the EJB deployment descriptor; this is shown in Listing 14.
                     </p>
                     <p><strong>Listing 14. Deployment descriptor for stateful session bean</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(431);"></div>
                     <div id="codewrap">
                        <div id="codewrap431"><pre> <code>&lt;session&gt;
   &lt;description&gt;Counter Service Bena&lt;/description&gt;
   &lt;ejb-name&gt;CounterServiceEJB&lt;/ejb-name&gt;
   &lt;local-home&gt;
      com.apress.prospring.ch13.ejb.CounterServiceHome&lt;/local-home&gt;
   &lt;local&gt;com.apress.prospring.ch13.ejb.CounterServiceLocal&lt;/local&gt;
   &lt;ejb-class&gt;com.apress.prospring.ch13.ejb.CounterServiceEJB&lt;/ejb-class&gt;
   &lt;session-type&gt;Stateful&lt;/session-type&gt;
   &lt;transaction-type&gt;Container&lt;/transaction-type&gt;
   &lt;env-entry&gt;
      &lt;env-entry-name&gt;ejb/BeanFactoryPath&lt;/env-entry-name&gt;
      &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
      &lt;env-entry-value&gt;applicationContext.xml&lt;/env-entry-value&gt;
   &lt;/env-entry&gt;
&lt;/session&gt;</code>
</pre></div>
                     </div><br><br><p>Accompanying this is the corresponding entry in the JBoss-specific deployment descriptor, shown in Listing 15.</p>
                     <p><strong>Listing 15. JBoss deployment descriptor for CounterServiceEJB</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(438);"></div>
                     <div id="codewrap">
                        <div id="codewrap438"><pre> <code>&lt;session&gt;
   &lt;ejb-name&gt;CounterServiceEJB&lt;/ejb-name&gt;
   &lt;local-jndi-name&gt;ejb/counterService&lt;/local-jndi-name&gt;
&lt;/session&gt;</code>
</pre></div>
                     </div><br><h4>EJB implementation summary</h4>
                     <p>Implementing EJBs with Spring is not drastically different from implementing EJBs using traditional approaches. However, Spring
                        support makes it simple to factor out the implementation of your EJBs into a POJO class, thus reducing the barriers to testing
                        and helping you deliver quality software.
                     </p>
                     <p>As you saw, implementing a stateless session bean is pretty painless&#8212;you have no special requirements to bear in mind. When
                        implementing stateful session beans, be aware of how the particular implementation of <code>BeanFactoryLocator</code> your bean is using affects the bean's ability to passivate successfully. If the <code>BeanFactory</code> returned by the <code>BeanFactoryLocator</code> is not serializable, then you need to remember to call <code>loadBeanFactory()</code> from <code>ejbActivate()</code> and <code>unloadBeanFactory()</code> from <code>ejbPassivate()</code>. Likewise, if the implementation of <code>BeanFactoryLocator</code> being used is not serializable, you need to set it to <code>null</code> in <code>ejbPassivate()</code> and, if you are not using the default implementation, re-create it in <code>ejbActivate()</code>.
                     </p>
                     <p>In some applications, you can get around this requirement if you can ensure that any resources you obtain from the <code>BeanFactory</code> are serializable. If this is the case, you can simply store the resources in <code>ejbCreate()</code> and then unload the <code>BeanFactory</code> immediately, with no need to reload and unload because the bean is activated and passivated. If you need to access resources
                        that aren't serializable, then consider using the <code>ContextSingletonBeanFactoryLocator</code> class to reduce the overhead of the <code>ApplicationContext</code> constantly being reloaded.
                     </p>
                     <p>That concludes the implementation of EJBs using Spring. Next, you see how to access these resources easily using Spring's
                        EJB access support classes.
                     </p>
                     <h3>Accessing EJBs with Spring</h3>
                     <p>Now that we have created our EJBs, we want, of course, to access them. Earlier, you saw how to use Spring's JNDI support to
                        simplify the lookup of JNDI resources. This comes in handy when we are trying to access the stateful <code>CounterServiceEJB</code>, because we can expose the home interface as a Spring-managed resource using <code>JndiObjectFactoryBean</code>. However, for the stateless <code>EchoServiceEJB</code>, we can go a step further. We use the <code>LocalStatelessSessionProxyFactoryBean</code> to create a proxy to the <code>EchoServiceEJB</code> and access it directly using the <code>EchoService</code> interface.
                     </p>
                     <p>In this section, we are going to demonstrate how you can access both stateless and stateful session beans in a simpler manner
                        using Spring's built-in features. We are going to jump ahead of ourselves slightly and show just the relevant methods from
                        the example servlet. We show the full servlet code later.
                     </p>
                     <h4>The JndiObjectLocator infrastructure component</h4>
                     <p>Before we jump into the juicy details of EJB access, we want to talk about the <code>JndiObjectLocator</code> class in Spring. Earlier, we showed you how you can use <code>JndiObjectFactoryBean</code> to look up a resource in JNDI automatically and make it available via DI. In this section, we show you how to use <code>LocalStatelessSessionProxyFactoryBean</code> to look up an EJB home interface in JNDI and automatically build a proxy to the EJB resource associated with that home interface.
                        Both <code>JndiObjectFactoryBean</code> and <code>LocalStatelessSessionProxyFactoryBean</code> share a common ancestor in <code>JndiObjectLocator</code>. This class, along with its parent, <code>JndiLocatorSupport</code>, provides the common logic for obtaining JNDI objects. What does this mean for you? Simply that configuring a <code>LocalStatelessSessionProxyFactoryBean</code> is just like configuring a <code>JndiObjectFactoryBean</code>, because most of the properties are exposed on the common base classes. You will see this in practice in the next two sections.
                     </p>
                     <h4>Accessing a stateless session bean via a proxy</h4>
                     <p>The easiest way to access a stateless session bean in a Spring application is to use a proxy. Spring provides two proxy <code>FactoryBean</code> classes for stateless session beans: <code>LocalStatelessSessionProxyFactoryBean</code> for local beans and <code>SimpleRemoteStatelessSessionProxyFactoryBean</code> for remote beans.
                     </p>
                     <p>Because the <code>EchoServiceEJB</code> is only exposed through a local interface, we use <code>LocalStatelessSessionProxyFactoryBean</code> in this example, but the configuration is identical for both classes. All you need to do to create the proxy is configure
                        the appropriate <code>FactoryBean</code> in your application configuration file.
                     </p>
                     <p>Listing 16 shows the configuration for the <code>echoService</code> bean, which is a proxy to the <code>EchoServiceEJB</code>.
                     </p>
                     <p><strong>Listing 16. Configuring a stateless session bean proxy</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(496);"></div>
                     <div id="codewrap">
                        <div id="codewrap496"><pre> <code>&lt;bean id="echoService"
      class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"&gt;
   &lt;property name="jndiName"&gt;
      &lt;value&gt;ejb/echoService&lt;/value&gt;
   &lt;/property&gt;
   &lt;property name="resourceRef"&gt;
      &lt;value&gt;true&lt;/value&gt;
   &lt;/property&gt;
   &lt;property name="businessInterface"&gt;
      &lt;value&gt;com.apress.prospring.ch13.ejb.EchoService&lt;/value&gt;
   &lt;/property&gt;
&lt;/bean&gt;</code>
</pre></div>
                     </div>
                     <p>The first thing you should notice here is that two of the properties, <code>jndiName</code> and <code>resourceRef</code>, are identical to those used in <code>JndiObjectFactoryBean</code>. This is because, as we described, <code>LocalStatelessSessionProxyFactoryBean</code> and <code>JndiObjectFactoryBean</code> share the same JNDI infrastructure base classes. The third property specified in the configuration, <code>businessInterface</code>, tells the <code>LocalStatelessSessionProxyFactoryBean</code> what interface the proxy should implement. In general, this is the business interface used for the EJB. You can use another
                        interface, perhaps to limit the methods exposed, but be sure that the methods in your interface match methods in the local
                        interface of the EJB. Remember that because <code>LocalStatelessSessionProxyFactoryBean</code> is a <code>FactoryBean</code>, Spring does not return the bean instance itself; instead, it returns the result of <code>FactoryBean.getObject()</code>, which in this case, is the proxy to the EJB.
                     </p>
                     <p>In the simple example servlet that we built, we placed all code related to the stateless <code>EchoServiceEJB</code> in the <code>doStatelessExample()</code> method (see Listing 17).
                     </p>
                     <p><strong>Listing 17. Working with the EJB proxy</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(514);"></div>
                     <div id="codewrap">
                        <div id="codewrap514"><pre> <code>private void doStatelessExample(ApplicationContext ctx, PrintWriter writer) {
   // Access the EJB proxy
   EchoService service = (EchoService) ctx.getBean("echoService");
   writer.write(service.echo("Foo"));
}</code>
</pre></div>
                     </div>
                     <p>Here you can see that the <code>EchoServiceEJB</code> is accessed, via the proxy, as though it were just a standard Spring bean. Using this approach makes it simple to swap out
                        EJBs for standard POJOs and vice versa without affecting any dependency components.
                     </p>
                     <h4>Simplifying stateful session bean access</h4>
                     <p>When accessing stateful session beans, be aware that currently, no proxy classes are available for you to use. However, you
                        can still simplify your code somewhat by using the JNDI support in Spring.
                     </p>
                     <p>The first step is to configure a bean in your <code>ApplicationContext</code> to access the EJB home interface, as shown in Listing 18.
                     </p>
                     <p><strong>Listing 18. Accessing EJB home using Spring</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(524);"></div>
                     <div id="codewrap">
                        <div id="codewrap524"><pre> <code>&lt;bean id="counterServiceHome"class="org.springframework.jndi.JndiObjectFactoryBean"&gt;
   &lt;property name="jndiName"&gt;
      &lt;value&gt;ejb/counterService&lt;/value&gt;
   &lt;/property&gt;
   &lt;property name="resourceRef"&gt;
      &lt;value&gt;true&lt;/value&gt;
   &lt;/property&gt;
&lt;/bean&gt;</code>
</pre></div>
                     </div>
                     <p>Here we simply use the <code>JndiObjectFactoryBean</code> to perform the lookup of the home interface automatically. In the code, we can avoid performing this lookup manually and
                        instead access the home interface using Spring. Listing 19 shows the example code for the stateful session bean.
                     </p>
                     <p><strong>Listing 19. Using the CounterServiceEJB</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(530);"></div>
                     <div id="codewrap">
                        <div id="codewrap530"><pre> <code>private void doStatefulExample(ApplicationContext ctx, PrintWriter writer,HttpSession session) {
   CounterService service = (CounterService) session.getAttribute("counterService");<br><br>   if (service == null) {<br><br>      try {
         CounterServiceHome home = (CounterServiceHome) ctx.getBean("counterServiceHome");<br><br>         service = (CounterService) home.create();<br><br>         session.setAttribute("counterService", service);
      } catch (CreateException ex) {
      ex.printStackTrace(writer);
      return;
      }
   }<br><br>writer.write("Counter: " + service.increment());
}</code>
</pre></div>
                     </div>
                     <p>Notice that we are able to avoid performing the JNDI lookup. Instead, we rely on Spring to do that for us. Because we are
                        storing the handle to the stateful session bean in the <code>HttpSession</code>, subsequent requests to this servlet use the same instance and thus, we see the counter on the page increase.
                     </p>
                     <h4>EJB access summary</h4>
                     <p>When using EJBs in your Spring-based applications, you have a lot of options for simplifying how you access them. When using
                        stateful session beans, you can use Spring's JNDI support to simplify the EJB home interface lookup. For stateless session
                        beans, you can go a few steps further and create a proxy to the EJB; this allows you to treat it as a POJO bean and frees
                        you and your application from EJB-specific details.
                     </p>
                     <h3>Testing EchoService and CounterService</h3>
                     <p>All that remains for this example is to finish off the example servlet and package up the application.</p>
                     <h4>Finishing the EjbTestServlet</h4>
                     <p>You have already seen the bulk of the code for the <code>EjbTestServlet</code> class in the <code>doStatelessExample()</code> and <code>doStatefulExample()</code> methods shown earlier. All that is left is the <code>doGet()</code> method, which loads the <code>ApplicationContext</code> and invokes both <code>doStatelessExample()</code> and <code>doStatefulExample()</code>. The code for <code>doGet()</code> is shown in Listing 20.
                     </p>
                     <p><strong>Listing 20. The doGet() method</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(560);"></div>
                     <div id="codewrap">
                        <div id="codewrap560"><pre> <code>protected void doGet(HttpServletRequest request,
   HttpServletResponse response) throws ServletException, IOException {<br><br>PrintWriter writer = response.getWriter();<br><br>response.setContentType("text/html");<br><br>writer.write("&lt;html&gt;&lt;head&gt;&lt;title&gt;EJB Samples&lt;/title&gt;&lt;/head&gt;");<br><br>writer.write("&lt;body&gt;");<br><br>writer.write("&lt;h1&gt;Echo Service (Stateless Session Bean)&lt;/h1&gt;");<br><br>doStatelessExample(ctx, writer);<br><br>writer.write("&lt;h1&gt;Counter Service (Stateful Session Bean)&lt;/h1&gt;");<br><br>doStatefulExample(ctx, writer, request.getSession());<br><br>writer.write("&lt;/body&gt;&lt;/html&gt;");<br><br>}</code>
</pre></div>
                     </div>
                     <p>This code is fairly basic, so we do not need to go into great detail explaining it; the only point of note is that the <code>ApplicationContext</code> is loaded in the <code>init()</code> method.
                     </p>
                     <h4>Packaging the sample application</h4>
                     <p>We are not going to go into great detail regarding the packaging of the sample application, but we do want to point out that
                        it actually has <em>two</em> <code>applicationContext.xml</code> files to configure Spring. The first, shown in Listing 21, goes inside the EJB JAR and is used by the EJBs for configuration.
                     </p>
                     <p><strong>Listing 21. ApplicationContext configuration for EJBs</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(591);"></div>
                     <div id="codewrap">
                        <div id="codewrap591"><pre> <code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd"&gt;<br><br>&lt;beans&gt;
   &lt;bean id="echoService"class="com.apress.prospring.ch13.ejb.EchoServiceImpl"/&gt;<br><br>   &lt;bean id="counterService"class="com.apress.prospring.ch13.ejb.CounterServiceImpl"/&gt;<br><br>&lt;/beans&gt;</code>
</pre></div>
                     </div>
                     <p>Here you can see that the POJO implementations of the <code>EchoService</code> and <code>CounterService</code> interfaces are configured and made available for access by the <code>EchoServiceEJB</code> and <code>CounterServiceEJB</code> classes. The second <code>applicationContext.xml</code> file sits in the <code>WEB-INF</code> directory of the Web applications war file. This file, shown in Listing 22, contains the configuration for the <code>EchoServiceEJB</code> proxy and the <code>CounterServiceEJB</code> home interface lookup.
                     </p>
                     <p><strong>Listing 22. Configuring the sample application</strong></p>
                     <div id="codebutton"><input type="button" name="btn" value="Copy to Clipboard" onClick="HighlightText(610);"></div>
                     <div id="codewrap">
                        <div id="codewrap610"><pre> <code>&lt;beans&gt;
   &lt;bean id="echoService"class="org.springframework.ejb.access.
      LocalStatelessSessionProxyFactoryBean"&gt;
   &lt;property name="jndiName"&gt;
      &lt;value&gt;ejb/echoService&lt;/value&gt;
   &lt;/property&gt;
   &lt;property name="resourceRef"&gt;
      &lt;value&gt;true&lt;/value&gt;
   &lt;/property&gt;
   &lt;property name="businessInterface"&gt;
      &lt;value&gt;com.apress.prospring.ch13.ejb.EchoService&lt;/value&gt;
   &lt;/property&gt;
   &lt;/bean&gt;
   &lt;bean id="counterServiceHome"class="org.springframework.jndi.JndiObjectFactoryBean"&gt;
      &lt;property name="jndiName"&gt;
         &lt;value&gt;ejb/counterService&lt;/value&gt;
      &lt;/property&gt;
      &lt;property name="resourceRef"&gt;
         &lt;value&gt;true&lt;/value&gt;
      &lt;/property&gt;
   &lt;/bean&gt;
&lt;/beans&gt;</code>
</pre></div>
                     </div>
                     <h4>Running the sample application</h4>
                     <p>Running the sample application is easy&#8212;just drop the ear file created by the build script into the deploy directory in JBoss
                        and you are on your way. The first time the screen is displayed, it looks something like Figure 3.
                     </p>
                     <center>
                        <p><a alt="Figure 3. First run of the sample application. Click on thumbnail to view full-sized image." href="images/jw-0214-springejb3.jpg" target="new_window"><img alt="" height="202" src="images/jw-0214-springejb3-thumb.jpg" width="350"></a></p>
                        <p><strong>Figure 3. First run of the sample application. Click on thumbnail to view full-sized image.</strong></p>
                     </center>
                     <p>Here, you can see that the <code>foo</code> message is echoed back to the screen by the <code>EchoServiceEJB</code> and that the <code>CounterServiceEJB</code> is currently displaying the count as one. Refreshing this screen results in the same message from <code>EchoServiceEJB</code>, but the counter displayed by <code>CounterServiceEJB</code> steadily increases.
                     </p>
                     <h3>EJB summary</h3>
                     <p>In this article, we looked at Spring's support for EJB, specifically focusing on support for stateless and stateful session
                        beans. Using Spring's base classes, you can easily create EJBs that are simply wrappers around dynamically loaded business
                        logic. Using this approach makes for easier testing and looser coupling in your application. When accessing stateless session
                        beans, Spring provides proxy support, freeing you of the coding burden of accessing EJB resources and decreasing the coupling
                        in your application.
                     </p>
                     <h3>Author Bio</h3>Rob Harrop is the lead architect of U.K.-based software company Cake Solutions Limited. As
                     part of Cake Solutions' team, Harrop has planned, designed, and
                     built enterprise-level applications for a variety of U.K.- and
                     U.S.-based clients, including the Metropolitan Police, DTi, and
                     National Union of Students Services Limited. In his spare time, he
                     is an avid reader and enjoys playing with new technology, his
                     current interests being Python and JavaServer Faces. 
                     
                     Jan Machacek is lead programmer of U.K.-based software company,
                     Cake Solutions Limited, where he has helped design and implement
                     enterprise-level applications for a variety of U.K.- and U.S.-based
                     clients. In his spare time, Machacek enjoys exploring software
                     architectures, nonprocedural and AI programming, and playing with
                     computer hardware. Like a proper computer geek, Machacek loves the
                     Star Wars and The Lord of the Rings series. He
                     lives in Manchester in the U.K.
                     <div class="separator">
                        <!-- xxxxxxxxxxxxxx -->
                     </div>
                     
<p>
<a name="discuss"></a><h3>Discuss</h3>
<a href="http://www.javaworld.com/javaforums/newpost.php?Cat=0&amp;Board=959744&amp;page=0">Start a new discussion</a> or jump into one of the threads below:</p>

<table>
<tr>
<td class="tdheader" style="padding:3px;">
<a href="http://www.javaworld.com/javaforums/postlist.php?Cat=0&amp;Board=959744&amp;page=0&amp;sb=1">
Subject
</a>
 
</td>

<td nowrap="nowrap" class="tdheader" style="padding:3px;width:2%;">
<a href="http://www.javaworld.com/javaforums/postlist.php?Cat=0&amp;Board=959744&amp;page=0&amp;sb=9">
Replies</a>
 
</td>
<td nowrap="nowrap" width="20%" class="tdheader" style="padding:3px;">
<a href="http://www.javaworld.com/javaforums/postlist.php?Cat=0&amp;Board=959744&amp;page=0&amp;sb=6">
Last post
</a>
 <img src="/javaforums/images/descend.gif" width="7" height="8" border="0" alt="" />
</td>
</tr>
<!-- BEGIN POST LOOP DO NOT DELETE --><tr>

<td align="left" style="padding:3px;" class="lighttable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=15501&amp;an=0&amp;page=0#Post15501">
Pro Spring: Spring and EJB</a><br /><em>By <a href="http://www.javaworld.com/javaforums/showprofile.php?Cat=0&amp;User=3&amp;Board=959744&amp;what=ubbthreads&amp;page=0"><font class="adminname">JavaWorld</font></a><img src="/javaforums/images/adm.gif" alt="Administrator" border="0" />
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="lighttable" valign="top">
12 
</td>
<td nowrap="nowrap" align="center" class="lighttable" valign="top">
<span class="small">10/05/06 10:25 AM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=37943&amp;Main=15501#Post37943">by Anonymous</a>
</span>
</td>
</tr><tr>

<td align="left" style="padding:3px;" class="darktable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=17671&amp;an=0&amp;page=0#Post17671">
where can I get the source code ?</a><br /><em>By Anonymous
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="darktable" valign="top">
5 
</td>
<td nowrap="nowrap" align="center" class="darktable" valign="top">
<span class="small">10/05/06 10:25 AM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=38743&amp;Main=17671#Post38743">by Anonymous</a>
</span>
</td>
</tr><tr>

<td align="left" style="padding:3px;" class="lighttable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=20362&amp;an=0&amp;page=0#Post20362">
Urgent!!!..getting illegal argument exception</a><br /><em>By Anonymous
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="lighttable" valign="top">
1 
</td>
<td nowrap="nowrap" align="center" class="lighttable" valign="top">
<span class="small">10/05/06 09:11 AM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=38647&amp;Main=20362#Post38647">by Anonymous</a>
</span>
</td>
</tr><tr>

<td align="left" style="padding:3px;" class="darktable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=15719&amp;an=0&amp;page=0#Post15719">
Small Detail</a><br /><em>By Anonymous
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="darktable" valign="top">
2 
</td>
<td nowrap="nowrap" align="center" class="darktable" valign="top">
<span class="small">10/05/06 07:59 AM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=38546&amp;Main=15719#Post38546">by Anonymous</a>
</span>
</td>
</tr><tr>

<td align="left" style="padding:3px;" class="lighttable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=23796&amp;an=0&amp;page=0#Post23796">
What is the calling sequence with ejb remote?</a><br /><em>By neal ravindran
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="lighttable" valign="top">
1 
</td>
<td nowrap="nowrap" align="center" class="lighttable" valign="top">
<span class="small">10/03/06 12:34 PM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=37403&amp;Main=23796#Post37403">by Anonymous</a>
</span>
</td>
</tr><tr>

<td align="left" style="padding:3px;" class="darktable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=24308&amp;an=0&amp;page=0#Post24308">
"Does it really work?", asked dummy.</a><br /><em>By MChan
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="darktable" valign="top">
0 
</td>
<td nowrap="nowrap" align="center" class="darktable" valign="top">
<span class="small">11/23/05 02:06 PM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=24308&amp;Main=24308#Post24308">by Anonymous</a>
</span>
</td>
</tr><tr>

<td align="left" style="padding:3px;" class="lighttable" valign="top" width="48%">
<img alt="." src="/javaforums/images/blank.gif" width="0" height = "11" hspace="0" />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=21924&amp;an=0&amp;page=0#Post21924">
Deployment failed</a><br /><em>By Anonymous
</em>

</td>

<td align="right" style="padding-right:6px;" nowrap="nowrap" class="lighttable" valign="top">
0 
</td>
<td nowrap="nowrap" align="center" class="lighttable" valign="top">
<span class="small">09/19/05 02:25 AM
<br />
<a href="http://www.javaworld.com/javaforums/showflat.php?Cat=0&amp;Number=21924&amp;Main=21924#Post21924">by Anonymous</a>
</span>
</td>
</tr><!-- END OF LOOP -->

</table>
</td>
</tr>
</table>

<br /><br />
                     
                     <!-- CONTENT ENDS HERE -->
                     
                     <!--stopindex-->
                     
                     
<!-- mypages: (none) -->
<!--story tools start-->
<script>
<!--
function MM_jumpMenu(targ,selObj,restore){ //v3.0
var test = "/adtran/solutionDetails.jsp?subject="
eval(targ+".location='"+test+"'+'"+selObj.options[selObj.selectedIndex].value+"'")
  if (restore) selObj.selectedIndex=0;
}

function MM_openBrWindow(theURL,winName,features) { //v2.0
  window.open(theURL,winName,features);
}
//-->
</script>
				<div id="storytools">
	      			<ul>
					  	<form method="post" name="print" action="/cgi-bin/mailto/x_java.cgi">
<input type="hidden" name="pagetosend" value="/export/home/httpd/javaworld/javaworld/jw-02-2005/jw-0214-springejb_p.html" />
<input type="hidden" name="pagename" value="/javaworld/jw-02-2005/jw-0214-springejb_p.html" />
<input type="hidden" name="pageurl" value="http://www.javaworld.com/javaworld/jw-02-2005/jw-0214-springejb_p.html" />
<input type="hidden" name="site" value="jw_enterprise" /><li><input type="image" title="print" src="/includes/styles/i/ico/print06-icon.gif" class="printer" alt="print" width="18" height="13" border="0" />
						<a href="javascript:document.forms.print.submit();">Print</a>
						</li> 
						</form>			  
						<li><img src="/includes/styles/i/ico/email-06-icon.gif" width="17" height="13" /><a href="javascript:;" onClick="MM_openBrWindow('/mailto/mailform.jsp?refpage=jw&pagetosend=/export/home/httpd/javaworld/javaworld/jw-02-2005/jw-0214-springejb_p.html&pagename=/javaworld/jw-02-2005/jw-0214-springejb_p.html&pageurl=/javaworld/jw-02-2005/jw-0214-springejb_p.html','Registration','scrollbars=yes,resizable=yes,width=510,height=500')">E-Mail article </a></li>			  
						<li><img src="/includes/styles/i/ico/fdbck06-icon.gif" width="14" height="13" /><a href="javascript:;" onClick="MM_openBrWindow('/askTheExpert.jsp?pagename=http://www.javaworld.com/javaworld/jw-02-2005/jw-0214-springejb_p.html&pagename=/javaworld/jw-02-2005/jw-0214-springejb_p.html&pageurl=/javaworld/jw-02-2005/jw-0214-springejb_p.html&pubsite=j','Registration','scrollbars=yes,resizable=yes,width=500,height=600')">Feedback</a></li>
						<li><img src="/includes/styles/i/ico/add-icon.gif" width="14" height="14" /><a href="javascript:location.href='http://del.icio.us/post?v=4;url='+encodeURIComponent(location.href)+';title='+encodeURIComponent(document.title)">Add to del.icio.us</a></li>
						<li class="next"><script src="/includes/nextlink.js"></script></li>						
					</ul>
				</div>
   <div class="separatorzero">
          <!-- xxxxxxxxxxxxxx -->
        </div>
        <!--story tools end--><a name="resources"></a><strong>Resources</strong><br><externallinks no-escaping="yes">
                        <div class="rxbodyfield">
                           <ul>
                              <li>This article excerpts Chapter 13, "Spring and J2EE," from <em>Pro Spring,</em> Rob Harrop, Jan Machacek (Apress, January 2005; ISBN1590594614):<br><a href="http://java.apress.com/book/bookDisplay.html?bID=405">http://java.apress.com/book/bookDisplay.html?bID=405</a></li>
                              <li><em>Expert One-on-One J2EE without EJB,</em> Rod Johnson and Juergen Hoeller (Wrox, 2004; ISBN0764558315):<br><a href="http://www.amazon.com/exec/obidos/ASIN/0764558315/javaworld">http://www.amazon.com/exec/obidos/ASIN/0764558315/javaworld</a></li>
                              <li>For more articles on EJB, browse the <strong>Enterprise JavaBeans (EJB)</strong> section of <em>JavaWorld'</em>s Topical Index:<br><a href="http://www.javaworld.com/channel_content/jw-ejbs-index.shtml">http://www.javaworld.com/channel_content/jw-ejbs-index.shtml</a></li>
                              <li>For more on Spring, read "Let Your Ant Enjoy Spring," Josef Betancourt (<em>JavaWorld,</em> February 2005):<br><a href="http://www.javaworld.com/javaworld/jw-02-2005/jw-0214-antspring.html">http://www.javaworld.com/javaworld/jw-02-2005/jw-0214-antspring.html</a></li>
                              <li>To learn how to use Spring with JSF, read "Put JSF to Work," Derek Yang Shen (<em>JavaWorld,</em> July 2004):<br><a href="http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html">http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html</a></li>
                           </ul>
                        </div>
                     </externallinks><br>
                     
</div>
               </div>
               
		<HTML><HEAD><META http-equiv=Pragma content=no-cache></HEAD>
<BODY>
<DIV class=box02>
<DIV id=box_cis>
<H5 class=cistrip>Partner Content</H5>
<TABLE cellSpacing=0 cellPadding=0 width="99%" bgColor=#faf8e8 border=0>
<TBODY>
<TR>
<TD vAlign=top width="25%">
<DIV align=center><!--1ST COLUMN OF CONTENT --><!-- maximum image dimension 175x50 --><IMG height=50 src="http://www.networkworld.com/cis/ibm_j559/ibm_logo.gif" width=135 border=0></DIV>
<H3 style="COLOR: #ab0538">Open Source Software Solutions </H3>
<P>Explore a universal platform of frameworks for open source on eclipse solutions coming on April 5, 2007. </P>
<P><A href="http://adserver.fattail.com/redir/redirect.asp?CID=202552" target=_blank>Continuum of open source </A></P></TD>
<TD vAlign=top width="25%">
<DIV align=center><!--2ND COLUMN OF CONTENT --><!-- maximum image dimension 175x50 --><IMG height=50 src="http://www.networkworld.com/cis/ibm_j559/ibm_websvcs.gif" width=165 border=0> </DIV>
<H3 style="COLOR: #ab0538">Build Secure Web Services </H3>
<P>Discover how to authenticate using a user ID and password, ensure integrity using digital signatures, and ensure confidentiality using encryption.</P>
<P><A href="http://adserver.fattail.com/redir/redirect.asp?CID=202553" target=_blank>Build your services now</A></P></TD>
<TD vAlign=top width="25%">
<DIV align=center><!--3RD COLUMN OF CONTENT --><!-- maximum image dimension 175x50 --><IMG height=50 src="http://www.networkworld.com/cis/ibm_j559/ibm_ratlsw_logo.gif" width=165 border=0> </DIV>
<H3 style="COLOR: #ab0538">Rational V7 Downloads</H3>
<P>Test-drive the IBM Rational V7 desktop products offering new capabilities for empowering global teams to speed SOA results.</P>
<P><A href="http://adserver.fattail.com/redir/redirect.asp?CID=202551" target=_blank>Free Rational trials </A></P></TD>
<TD class=end vAlign=top width="25%">
<DIV align=center><!--4TH COLUMN OF CONTENT --><!-- maximum image dimension 175x50 --><IMG height=50 src="http://www.networkworld.com/cis/ibm_j559/ibm_soastrip.gif" width=165 border=0></DIV>
<H3 style="COLOR: #ab0538">New! Rational SOA Testing Open Beta</H3>
<P>IBM Rational invites you to participate in our open beta program for testing SOA applications. </P>
<P><A href="http://adserver.fattail.com/redir/redirect.asp?CID=202550" target=_blank>Sign up today! </A></P></TD></TR></TBODY></TABLE></DIV></DIV><img src=http://ai.hitbox.com/ai?hb=DM550223OGAN&ai=EMC-CIS_J559_IBM_FEB07 width=1 height=1 border=0></BODY></HTML>


<br clear="all"/>
 
<!-- begin ad tag -->
<SCRIPT LANGUAGE="JavaScript1.1" SRC="http://ad.doubleclick.net/adj/idg.us.nwf.jw_enterprise/;pos=bottom;sz=120x90;tile=6;ord=014914?" ></SCRIPT>
<script>
if ((!document.images && navigator.userAgent.indexOf("Mozilla/2.") >= 0)  || navigator.userAgent.indexOf("WebTV")>= 0) {
document.write('<A HREF="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;pos=bottom;sz=120x90;tile=6;ord=014914?" TARGET="_blank">');
document.write('<IMG SRC="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;pos=bottom;sz=120x90;tile=6;ord=014914?" WIDTH="120" HEIGHT="90" BORDER="0" ALT="Click Here"></A>');
}
</script>
<NOSCRIPT>
<A HREF="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;pos=bottom;sz=120x90;tile=6;ord=014914?" TARGET="_blank">
<IMG SRC="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;pos=bottom;sz=120x90;tile=6;ord=014914?" WIDTH="120" HEIGHT="90" BORDER="0" ALT="alt text">Click Here</A>
</NOSCRIPT>
<!-- end ad tag -->

               <div class="separator">
                  <!-- xxxxxxxxxxxxxx -->
               </div>
               <!--stopindex-->







<div id="imu2">
  
  <NOLAYER>
  <IFRAME id="imu2" src="http://ad.doubleclick.net/adi/idg.us.nwf.jw_enterprise/;pos=imu2;sz=336x280;ptile=5;type=news;ord=014914?" width="336" height="280" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no">
  <A href="http://ad.doubleclick.net/jump/idg.us.nwf.jw_enterprise/;abr=!ie;pos=imu2;sz=336x280;ptile=5;type=news;ord=014914?">
  <IMG src="http://ad.doubleclick.net/ad/idg.us.nwf.jw_enterprise/;abr=!ie;pos=imu2;sz=336x280;ptile=5;type=news;ord=014914?" border="0" width="336" height="280"></A>
  </IFRAME>
  </NOLAYER>
  <ILAYER id="imu2" visibility="hidden" width="336" height="280"></ILAYER>
	<script> imusrc = "http://ad.doubleclick.net/adi/idg.us.nwf.jw_enterprise/;pos=imu2;sz=336x280;ptile=3;type=news;ord=";</script>
</div>
               <div id="sponsoredlinks">
	<h5>Sponsored links</h5>
	<DIV id="toplinks">
   <p>
         <a href="http://ad.doubleclick.net/clk;86360745;12174868;t?http://www.ej-technologies.com/products/install4j/landing.html" title="ej-technologies GmbH" onclick="" target="" name="&amp;lid=rid_94549 831311 ej-Technologies Text Link JW">
            <span>Java Installer Builder</span>install4j is easy to use, amazingly powerful and creates beautiful installers for all platforms. Try out the free trial version.</a>
         <strong> - ej-technologies GmbH</strong>
      </p><p class="dotted"><img alt="" height="2" width="400" src="/graphics/templates/spacer.gif"/></p><p>
         <a href="http://ad.doubleclick.net/clk;88837542;12174868;z?http://www.junitfactory.com/?utm_source=javaworld&amp;utm_medium=text_link&amp;utm_content=junit_factory&amp;utm_campaign=march_may" title="www.junitfactory.com" onclick="" target="_blank" name="&amp;lid=rid_95344 831316 Agitar Text Link JWROS">
            <span>JUnit Test Generation</span>Submit Java. Get back FREE JUnit. Try it!</a>
         <strong> - www.junitfactory.com</strong>
      </p>
</DIV>
<DIV id="middlelinks">
   <TABLE cellPadding="0" cellSpacing="0" id="nwtextlinks">
      <TBODY>
         <tr>
            <td>
               <a href="http://ad.doubleclick.net/clk;95675857;12174868;g?http://www.defyallchallenges.com" title="Microsoft Corp" onclick="" target="_blank" name="&amp;lid=rid_97786 872677 Microsoft VS2005 Text Link JWROS">Defy all challenges with Microsoft(r) Visual Studio 2005</a>
               <strong>- Microsoft Corp</strong>
            </td>
            <td>
               <a href="http://ad.doubleclick.net/clk;94414897;12174868;a?http://www.agitar.com/solutions/products/on_site_trial.html?utm_source=javaworld&amp;utm_medium=textlink&amp;utm_content=agitarone-freetrial&amp;utm_campaign=javaworld-agitarone-april" title="Agitar" onclick="" target="_blank" name="&amp;lid=rid_97168 886476 Agitar April Text Link ">Automate JUnit generation for fast, easy Java unit testing. Free trial! </a>
               <strong>- Agitar</strong>
            </td></tr><tr><td>
               <a href="http://ad.doubleclick.net/clk;94925576;12174868;b?http://www.ibm.com/developerworks/websphere/education/enablement/curriculum/#wbi-modeler&amp;S_TACT=105AGY41&amp;S_CMP=JWSOAEDU" title="IBM" onclick="" target="" name="&amp;lid=rid_97435 879693 C589 IBM JAVAWORLD Q1 SOAEDU">IBM WebSphere Business Modeler V6: Learn the basics using a hands-on lab approach.</a>
               <strong>- IBM</strong>
            </td>
            <td>
               <a href="http://ad.doubleclick.net/clk;94926006;12174868;q?http://www.ibm.com/developerworks/websphere/education/enablement/curriculum/#wesb&amp;S_TACT=105AGY41&amp;S_CMP=JWSOAEDU" title="IBM" onclick="" target="" name="&amp;lid=rid_97436 879694 C589 IBM JAVAWORLD Q1 SOAEDU">Learn how to build and deploy mediation integration solutions</a>
               <strong>- IBM</strong>
            </td></tr><tr></tr>
      </TBODY>
   </TABLE>
</DIV>
	<div id="bottomlinks">
		<H4><A href="http://www.industrybrains.com/">Buy a link now.</A></H4>
<p style="width:400px;"><a href="http://links.industrybrains.com/click?sid=620&amp;rqctid=5123&amp;pos=1&amp;lid=431331&amp;cid=103597&amp;pr=2&amp;tstamp=20070417134522&amp;url=http://www.lunarpages.com/id/IB%26campaign%3dJW" target="blank">Reliable and Affordable Web Hosting Services</a><br>Ideal webmaster solutions for small to large sites from Lunarpages. Save $26 with Coupon Code: 26off
</p>
<p style="width:400px;"><a href="http://links.industrybrains.com/click?sid=620&amp;rqctid=5123&amp;pos=2&amp;lid=426845&amp;cid=101068&amp;pr=2&amp;tstamp=20070417134522&amp;url=https://events.webdialogs.com/Portal/WipEvents/register.php%3fid%3d5278e3af29625340fb894dddc02e4adf%26sourceID%3d" target="blank">Cost Effective SOA Management &amp; Runtime Governance</a><br>Webinar April 4th, Using JaxView for SOA Management &amp; Runtime governance.$35 gift card for attending
</p>
<p style="width:400px;"><a href="http://links.industrybrains.com/click?sid=620&amp;rqctid=5123&amp;pos=3&amp;lid=430182&amp;cid=103398&amp;pr=2&amp;tstamp=20070417134522&amp;url=http://ad.doubleclick.net/clk%3b91779202%3b16089618%3bt%3fhttp://dualbrand.seagatestorage.com" target="blank">Maxtor Diamondmax/Mobilemax Drives From Seagate .</a><br>Seagate is now the only partner you need for advanced storage solutions. Learn the benefits here.
</p>
		<!--<H4><A href="http://www.industrybrains.com/">Buy a link now.</A></H4><br clear="all">
		<script type="text/javascript">
		adsonar_pid=462761; // this is the original javaworld pid
		adsonar_ps=1061721;
		adsonar_zw=460;
		adsonar_zh=190;
		adsonar_jv='ads.adsonar.com';
		</script>
		<script language="JavaScript" src="http://js.adsonar.com/js/adsonar.js"></script>	 -->
		<br clear="all">
	</div>
</div>
               <div class="separator">
                  <!-- xxxxxxxxxxxxxx -->
               </div>
               <div id="rcfooter"><strong>RESEARCH CENTERS: </strong>
<a href="http://www.javaworld.com/channel_content/jw-core-index.html"><strong>Java Standard Edition</strong></a> | 
<a href="http://www.javaworld.com/channel_content/jw-enterprise-index.html"><strong>Java Enterprise Edition</strong></a> | 
<a href="http://www.javaworld.com/channel_content/jw-micro-index.html"><strong>Java Micro Edition </strong></a> | 
<a href="http://www.javaworld.com/channel_content/jw-applied-index.html"><strong>Development Tools</strong></a>

<div align="center"><a href="http://www.javaworld.com/info/jw-about-index.html">About Us</a> | <a href="http://www.javaworld.com/info/jw-advertise.html">Advertise</a> | <a href="http://www.javaworld.com/info/jw-masthead.html">Contact Us</a> | <a href="http://www.javaworld.com/info/jw-privacy.html">Terms of Service/Privacy</a> </div>
<div align="center"><a href="http://www.javaworld.com/javaworld/common/jw-copyright.html">Copyright</a>, 2006-2007 Network World, Inc. All rights reserved.</div>
</div>
            </div>
            <div id="footer"><span><a href="http://www.idg.net"><strong>IDG Network:</strong></a> <a href="http://www.cio.com">CIO</a>  <a href="http://www.computerworld.com">Computerworld</a> <a href="http://www.csoonline.com/">CSO</a> <a href="http://demo.com/">Demo</a>  
<a href="http://www.games.net">Games.net</a>
<a href="http://www.idgconnect.com">IDGconnect.com</a>
 <a href="http://www.infoworld.com">Infoworld</a> <a href="http://www.itworldcanada.com">IT World Canada</a> <a href="http://www.linuxworld.com">Linuxworld.com</a> <a href="http://www.macworld.com">Macworld</a>  <a href="http://www.networkworld.com">NetworkWorld.com</a> <a href="http://www.oswmag.com/">Outsourcing World</a> <a href="http://www.pcworld.com">PC World</a> <a href="http://www.playlistmag.com">Playlistmag.com</a></span></div>
<!-- start Vibrant Media IntelliTXT script section -->

<script type="text/javascript" src="http://javaworld.us.intellitxt.com/intellitxt/front.asp?ipid=3407"></script>

<script language="javascript">
	if (typeof menu_lookup == "function") menu_lookup();
</script>
<!-- end Vibrant Media IntelliTXT script section -->
<!--include virtual="/includes/ads-interstitial.html"-->

         </div>
      </div>
   </body>
</html>