blob: 317f24156635a58759925c80f9f01f6440a01e6b [file] [log] [blame]
<html><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>OpenEJB Specification --
for OpenEJB version 0.7.3</title><link href="spec.css" rel="stylesheet"><link href="/images/favicon.ico" rel="SHORTCUT ICON"></head><body marginwidth="0" marginheight="0" leftmargin="0" bottommargin="0" topmargin="0" vlink="#6763a9" link="#6763a9" bgcolor="#ffffff"><a name="top"></a><table height="400" width="712" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#7270c2" align="left" valign="top" width="20"><img border="0" height="1" width="1" src="images/dotTrans.gif"></td><td bgcolor="#7270c2" align="left" valign="top" width="95"><img border="0" height="1" width="1" src="images/dotTrans.gif"></td><td align="left" valign="top" width="7"><img height="1" width="1" border="0" src="images/dotTrans.gif"></td><td align="left" valign="top" width="40"><img border="0" height="6" width="40" src="images/dotTrans.gif"></td><td bgcolor="#5A5CB8" align="left" valign="top" width="430"><img border="0" height="6" width="430" src="images/top_2.gif"></td><td bgcolor="#E24717" align="left" valign="top" width="120"><img src="images/top_3.gif" width="120" height="6" border="0"></td></tr><tr><td align="left" valign="top" bgcolor="#7270c2" width="20"><img height="1" width="1" border="0" src="images/dotTrans.gif"></td><td align="left" valign="top" bgcolor="#7270c2" width="95"><img height="1" width="1" border="0" src="images/dotTrans.gif"></td><td align="left" valign="top" bgcolor="#ffffff" width="7"></td><td align="left" valign="top" width="40"><img border="0" height="1" width="1" src="images/dotTrans.gif"></td><td align="left" valign="middle" width="430"><a href="faq.html"><span class="menuTopOff">[ f a q ]</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.codehaus.org/openejb"><span class="menuTopOff">[ w i k i ]</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://archive.openejb.codehaus.org/user/"><span class="menuTopOff">[ l i s t s ]</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://cvs.openejb.org/"><span class="menuTopOff">[ c v s ]</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://jira.codehaus.org/secure/BrowseProject.jspa?id=10401"><span class="menuTopOff">[ b u g s ]</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img border="0" height="2" width="1" src="images/dotTrans.gif"></td><td align="left" valign="top" height="20" width="120">&nbsp;</td></tr><tr><td align="left" valign="top" bgcolor="#7270c2" width="20"><img border="0" height="3" width="20" src="images/dotTrans.gif"></td><td align="left" valign="top" bgcolor="#7270c2" width="95"><img border="0" height="3" width="105" src="images/line_sm.gif"></td><td align="left" valign="top" bgcolor="#a9a5de" width="7"><img border="0" height="3" width="7" src="images/line_sm.gif"></td><td align="left" valign="top" width="40"><img border="0" height="3" width="40" src="images/line_light.gif"></td><td align="left" valign="top" width="430"><img border="0" height="3" width="430" src="images/line_light.gif"></td><td align="left" valign="top" width="120"><img height="1" width="1" border="0" src="images/dotTrans.gif"></td></tr><tr><td align="left" valign="top" bgcolor="#7270c2"><img border="0" height="10" width="20" src="images/dotTrans.gif"></td><td align="left" valign="top" bgcolor="#7270c2" width="95"><img border="0" height="2" width="1" src="images/dotTrans.gif"><br><table cellspacing="0" cellpadding="0" border="0"><tr><td align="left" valign="top"><span class="subMenuOn">Main</span></td></tr><tr><td align="left" valign="top"><a href="index.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Welcome!</span></a></td></tr><tr><td align="left" valign="top"><a href="download.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Download</span></a></td></tr><tr><td align="left" valign="top"><a href="lists.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Mailing Lists</span></a></td></tr><tr><td align="left" valign="top"><a href="cvs.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Source Code</span></a></td></tr><tr><td align="left" valign="top"><a href="contributors.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
The Team</span></a></td></tr><tr><td align="left" valign="top"><a href="status.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Status</span></a></td></tr></table><table cellspacing="0" cellpadding="0" border="0"><tr><td align="left" valign="top"><span class="subMenuOn">Users</span></td></tr><tr><td align="left" valign="top"><a href="quickstart.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Quickstart</span></a></td></tr><tr><td align="left" valign="top"><a href="hello-world.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Hello World!</span></a></td></tr><tr><td align="left" valign="top"><a href="cmp_entity_postgresql.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
CMP Example</span></a></td></tr><tr><td align="left" valign="top"><a href="cmp_guide.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
CMP Guide</span></a></td></tr><tr><td align="left" valign="top"><a href="deploy.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Deploy</span></a></td></tr><tr><td align="left" valign="top"><a href="start-command.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Startup</span></a></td></tr><tr><td align="left" valign="top"><a href="validate.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Validation</span></a></td></tr><tr><td align="left" valign="top"><a href="config_containers.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Configuration</span></a></td></tr><tr><td align="left" valign="top"><a href="properties.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Properties</span></a></td></tr></table><table cellspacing="0" cellpadding="0" border="0"><tr><td align="left" valign="top"><span class="subMenuOn">Servers</span></td></tr><tr><td align="left" valign="top"><a href="embedded.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Local Server</span></a></td></tr><tr><td align="left" valign="top"><a href="remote-server.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Remote Server</span></a></td></tr><tr><td align="left" valign="top"><a href="tomcat.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Tomcat</span></a></td></tr><tr><td align="left" valign="top"><a href="geronimo.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Geronimo</span></a></td></tr></table><table cellspacing="0" cellpadding="0" border="0"><tr><td align="left" valign="top"><span class="subMenuOn">Integrators</span></td></tr><tr><td align="left" valign="top"><a href="whyopenejb.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Why OpenEJB</span></a></td></tr><tr><td align="left" valign="top"><a href="containersystem.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Overview</span></a></td></tr><tr><td align="left" valign="top"><a href="design_openejb.html"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Design</span></a></td></tr><tr><td align="left" valign="top"><a href="OpenEJB_presentaion.ppt"><span class="subMenuOff">&nbsp;&nbsp;&nbsp;
Presentation</span></a></td></tr></table><img border="0" height="15" width="1" src="images/dotTrans.gif"><br><img border="0" height="3" width="105" src="images/line_sm.gif"><br><A href="http://codehaus.org"><IMG alt="The Codehaus" border="0" height="17" width="88" src="http://www.openejb.org/codehaus-smaller.png"></A></td><td align="left" valign="top" bgcolor="#a9a5de" width="7">&nbsp;</td><td align="left" valign="top" width="40">&nbsp;</td><td valign="top" width="430" rowspan="4"><table width="430" cellspacing="0" cellpadding="0" border="0" rows="2" cols="1"><tr><td align="left" valign="top"><br><img width="200" vspace="0" src="./images/logo_ejb2.gif" hspace="0" height="55" border="0"><br><img src="images/dotTrans.gif" hspace="0" height="7" border="0"><br><span class="pageTitle">OpenEJB Specification</span><br><span class="pageSubTitle">for OpenEJB version 0.7.3</span><br><p><span class="author">by Richard Monson-Haefel and David Blevins</span><br></p><img src="images/dotTrans.gif" hspace="0" height="1" border="0"></td></tr></table><p></p><p></p><br><span class="toc"><a href="#Introduction">1<img border="0" height="1" width="5" src="images/dotTrans.gif">Introduction</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#Overview">1.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Overview</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#modular.design">1.1.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Monolithic vs. Modular Design</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#contract.concept">1.1.2<img border="0" height="1" width="5" src="images/dotTrans.gif">The container-server contract</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#no.formal.contract">1.1.3<img border="0" height="1" width="5" src="images/dotTrans.gif">No formal contract in the EJB specification</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#need.contract">1.1.4<img border="0" height="1" width="5" src="images/dotTrans.gif">The need for a contract</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#have.contract">1.2<img border="0" height="1" width="5" src="images/dotTrans.gif">The OpenEJB server-container contract</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#servers.role">1.2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">The application server&rsquo;s role</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#containers.role">1.2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">The container&rsquo;s role</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#architecture">1.3<img border="0" height="1" width="5" src="images/dotTrans.gif">The Architecture</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#arch.overview">1.3.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Overview</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#containers">1.3.2<img border="0" height="1" width="5" src="images/dotTrans.gif">The containers</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#primary.services">1.3.3<img border="0" height="1" width="5" src="images/dotTrans.gif">The primary services</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#intravm.server">1.3.4<img border="0" height="1" width="5" src="images/dotTrans.gif">The IntraVM server</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#customizable">1.3.5<img border="0" height="1" width="5" src="images/dotTrans.gif">Customizable</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#flexible">1.3.6<img border="0" height="1" width="5" src="images/dotTrans.gif">Flexible</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#open.source">1.4<img border="0" height="1" width="5" src="images/dotTrans.gif">OpenEJB is Open Source</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#license">1.4.1<img border="0" height="1" width="5" src="images/dotTrans.gif">The OpenEJB License</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#open.source.advantage">1.4.2<img border="0" height="1" width="5" src="images/dotTrans.gif">The open source advantage</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#community">1.4.3<img border="0" height="1" width="5" src="images/dotTrans.gif">The open source community</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#open.source.synergy">1.4.4<img border="0" height="1" width="5" src="images/dotTrans.gif">The synergy of OpenEJB and open source</a><br></span><span class="toc"><a href="#openejb.contract">2<img border="0" height="1" width="5" src="images/dotTrans.gif">The Server-Container Contract</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#contract.overview">2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Overview</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#openejb.resp">2.1.1<img border="0" height="1" width="5" src="images/dotTrans.gif">OpenEJB Responsibilities</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#server.resp">2.1.2<img border="0" height="1" width="5" src="images/dotTrans.gif">Server Responsibilities</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#contract.api">2.1.3<img border="0" height="1" width="5" src="images/dotTrans.gif">The Server-Container Interface</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#openejb.api">2.1.3.1<img border="0" height="1" width="5" src="images/dotTrans.gif">OpenEJB</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#container.api">2.1.3.2<img border="0" height="1" width="5" src="images/dotTrans.gif">Container</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.container.api">2.1.3.3<img border="0" height="1" width="5" src="images/dotTrans.gif">RpcContainer</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#deploymentinfo.api">2.1.3.4<img border="0" height="1" width="5" src="images/dotTrans.gif">DeploymentInfo</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#api.proxyinfo">2.1.3.5<img border="0" height="1" width="5" src="images/dotTrans.gif">ProxyInfo</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#api.openejbexception">2.1.3.6<img border="0" height="1" width="5" src="images/dotTrans.gif">OpenEJBException</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#api.applicationexception">2.1.3.7<img border="0" height="1" width="5" src="images/dotTrans.gif">ApplicationException</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#api.invalidatereferenceexception">2.1.3.8<img border="0" height="1" width="5" src="images/dotTrans.gif">InvalidateReferenceException</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#api.systemexception">2.1.3.9<img border="0" height="1" width="5" src="images/dotTrans.gif">SystemException</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#api.envprops">2.1.3.10<img border="0" height="1" width="5" src="images/dotTrans.gif">EnvProps</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#rpc.container.contract">2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">Server-RpcContainer Contract</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#rpc.invoke.policy">2.2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Invoke Policies</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.parameters">2.2.1.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Parameters</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.deployid">2.2.1.1.1<img border="0" height="1" width="5" src="images/dotTrans.gif">deployID</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.callmethod">2.2.1.1.2<img border="0" height="1" width="5" src="images/dotTrans.gif">callMethod</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.args">2.2.1.1.3<img border="0" height="1" width="5" src="images/dotTrans.gif">args</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.primkey">2.2.1.1.4<img border="0" height="1" width="5" src="images/dotTrans.gif">primKey</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.securityidentity">2.2.1.1.5<img border="0" height="1" width="5" src="images/dotTrans.gif">securityIdentity</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#rpc.invoke.returnvalues">2.2.1.2<img border="0" height="1" width="5" src="images/dotTrans.gif">Return Values</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#returnvalues.void">2.2.1.2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">void</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#returnvalues.primitives">2.2.1.2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">primitive types</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#returnvalues.serializable">2.2.1.2.3<img border="0" height="1" width="5" src="images/dotTrans.gif">Serializable types</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#returnvalues.arrays">2.2.1.2.4<img border="0" height="1" width="5" src="images/dotTrans.gif">Array Value types</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#returnvalues.remote.references">2.2.1.2.5<img border="0" height="1" width="5" src="images/dotTrans.gif">Remote References</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#exceptions">2.2.1.3<img border="0" height="1" width="5" src="images/dotTrans.gif">Exceptions</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#applicationexception">2.2.1.3.1<img border="0" height="1" width="5" src="images/dotTrans.gif">ApplicationException</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#invalidatereferenceexception">2.2.1.3.2<img border="0" height="1" width="5" src="images/dotTrans.gif">InvalidateReferenceException</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#systemexception">2.2.1.3.3<img border="0" height="1" width="5" src="images/dotTrans.gif">SystemException</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#ejbobject">2.2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">The EJBObject</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#remote.interface">2.2.2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Remote Interface Methods</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#ejbobject.interface">2.2.2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">EJBObject Interface Methods</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#getEJBHome">2.2.2.2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">getEJBHome</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#getHandle">2.2.2.2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">getHandle</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#getPrimaryKey">2.2.2.2.3<img border="0" height="1" width="5" src="images/dotTrans.gif">getPrimaryKey( )</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#isIdenticial">2.2.2.2.4<img border="0" height="1" width="5" src="images/dotTrans.gif">isIdenticial</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#remove">2.2.2.2.5<img border="0" height="1" width="5" src="images/dotTrans.gif">remove</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#ejbhome">2.2.3<img border="0" height="1" width="5" src="images/dotTrans.gif">The EJBHome</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#home.interface">2.2.3.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Home Interface Methods</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#ejbhome.interface">2.2.3.2<img border="0" height="1" width="5" src="images/dotTrans.gif">EJBHome Interface Methods</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#getEJBMetaData">2.2.3.2.1<img border="0" height="1" width="5" src="images/dotTrans.gif">getEJBMetaData</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#getHomeHandle">2.2.3.2.2<img border="0" height="1" width="5" src="images/dotTrans.gif">getHomeHandle</a><br></span><span class="toc"><img border="0" height="1" width="45" src="images/dotTrans.gif"><a href="#remove">2.2.3.2.3<img border="0" height="1" width="5" src="images/dotTrans.gif">remove</a><br></span><span class="toc"><a href="#api.service.provider">3<img border="0" height="1" width="5" src="images/dotTrans.gif">The Service Provider Interface</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#connector.support">3.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Connector Support</a><br></span><span class="toc"><img border="0" height="1" width="30" src="images/dotTrans.gif"><a href="#connector.notes">3.1.1<img border="0" height="1" width="5" src="images/dotTrans.gif">Note on January 4, 2001</a><br></span><span class="toc"><a href="#The Core OpenEJB Implementation">4<img border="0" height="1" width="5" src="images/dotTrans.gif">The Core OpenEJB Implementation</a><br></span><span class="toc"><a href="#Vendor Interoperability">5<img border="0" height="1" width="5" src="images/dotTrans.gif">Vendor Interoperability</a><br></span><span class="toc"><a href="#customization">6<img border="0" height="1" width="5" src="images/dotTrans.gif">OpenEJB Customization</a><br></span><span class="toc"><img border="0" height="1" width="15" src="images/dotTrans.gif"><a href="#factory">6.1<img border="0" height="1" width="5" src="images/dotTrans.gif">The OpenEJB Factory</a><br></span><br><a name="Introduction"><h2>Introduction</h2></a>
<a name="Overview"><h3>Overview</h3></a>
<a name="modular.design"><h4>Monolithic vs. Modular Design</h4></a>
<p><span class="bodyBlack">OpenEJB represents a
revolution in application server design, a view that application servers should
be modular, not monolithic. A modular application server is built from
subsystems rather than constructed as one huge, tightly coupled platform.
Modularization of application server software allows vendors to focus on their
core competencies instead of reinventing every subsystem from scratch to create
a complete platform. Not only is modularization possible, OpenEJB makes it a
reality.</span></p>
<p><span class="bodyBlack">OpenEJB is an EJB
container system - not a monolithic EJB server - that can be plugged into any
application server to make it a fully compliant EJB server. </span></p>
<p><span class="bodyBlack">The Enterprise JavaBeans
API itself does not specify a separation of responsibilities among the
application server, the container, and the primary services (transaction,
security, and connectors). As a result, EJB vendors must build proprietary
monolithic application servers to support all the subsystems needed for a
complete EJB platform.</span></p>
<p><span class="bodyBlack">OpenEJB clearly defines
the separation of its responsibilities as a container system from those of the
application server that hosts it, and from the primary services that support
it. This decoupling enables vendors of application servers, transaction
managers, and providers of security services and connectors to focus on their
own specialties, while OpenEJB focuses on delivering a high-speed container
system that combines the services into a single EJB platform.</span></p>
<p><span class="bodyBlack">This Introduction Section
examines the need for a separation of responsibilities among application
server, container, and primary services, and how OpenEJB provides a powerful
container system and a set of programming interfaces that make this
modularization possible.</span></p>
<a name="contract.concept"><h4>The container-server contract</h4></a>
<p><span class="bodyBlack">Enterprise JavaBeans
defines a portable server-side component model for enterprise computing. EJB
clearly specifies a bean-container contract and a client-server contract that
allow developers to switch EJB server products in an enterprise system without
significant redevelopment costs. While the EJB specification defines
portability in terms of the enterprise-bean and EJB-client programming models,
the EJB servers themselves - all the subsystems that lie between the enterprise
beans and the client applications - remain proprietary. </span></p>
<a name="no.formal.contract"><h4>No formal contract in the EJB specification</h4></a>
<p><span class="bodyBlack">The Enterprise JavaBeans
specification does not define a server-container contract. This omission is
intentional; it was done to facilitate maximum flexibility for vendors defining
EJB server technologies. Beyond isolating the beans from the application
server, the container&rsquo;s responsibility in the EJB system is vague. At the
application server level, the EJB specification defines only a bean-container
contract and does not define the server-container contract. </span></p>
<p><span class="bodyBlack">It is difficult to determine
exactly, for example, which is responsible for resource management and other
services, the container or the application server. Without a clear
separation of responsibilities between the container and the application
server, EJB vendors must bear the burden of implementing the entire platform,
including the distributed-object service, naming, transaction management,
security, and EJB container. As a result, commercial EJB servers tend to be
complex monolithic platforms with proprietary and hidden implementations. </span></p>
<a name="need.contract"><h4>The need for a contract</h4></a>
<p><span class="bodyBlack">The advantage to defining a
server-container contract is that it allows third-party vendors to produce
containers that can plug into any application server. If the responsibilities
of the container and application server are clearly defined, then vendors who
specialize in the technologies that support these different responsibilities
can focus on developing the container or application server that best matches
their core competencies. Web vendors focus on managing web requests; CORBA
vendors focus on distributed-object requests; TP monitors focus on transaction
management. Meanwhile, the EJB container vendor focus on managing the
enterprise beans within the container.&nbsp; Until now this separation of
responsibilities did not exist. </span></p>
<a name="have.contract"><h3>The OpenEJB server-container contract</h3></a>
<p><span class="bodyBlack">OpenEJB is a pre-built,
self-contained, portable EJB 1.1 container system that can be plugged into any
application server environment. OpenEJB provides a clear separation of
responsibilities between the EJB container and the EJB server. The application
server and OpenEJB container system interact through an elegant and powerful
programming interface, which forms the server-container contact. This contract
is defined by the Server-Container Interface (SCI), a small, simple, and
refined set of classes and interfaces.</span></p>
<a name="servers.role"><h4>The application server&rsquo;s role</h4></a>
<p><span class="bodyBlack">Application servers that
use OpenEJB are responsible for providing client applications with naming and
remote access to the application server. Its services may include providing
JNDI and proxy implementations that fulfill the client-server contract of the EJB
programming model. In application servers that will use OpenEJB locally, such
as servlet engines, OpenEJB already provides the necessary JNDI and proxy
implementations. When a client makes a request on a remote bean reference, the
application server delivers the request to the OpenEJB container system, which
delegates the request to the appropriate enterprise bean and applies
transaction, connectors and security services appropriately. </span></p>
<p><span class="bodyBlack">The Apache Tomcat server
is a good example of an application server that could easily be extended using
OpenEJB to provide its servlets with a complete EJB container system.&nbsp; Enydra
and OpenORB are other examples of application servers that would benefit from
OpenEJB integration.</span></p>
<a name="containers.role"><h4>The container&rsquo;s role</h4></a>
<p><span class="bodyBlack">OpenEJB manages the
enterprise bean&rsquo;s lifecycle and coordinates the application of transactions
(distributed or local), connectors, and security as defined by the EJB 1.1
specification. To manage these tasks in a way that is flexible and
customizable, OpenEJB also enforces a separation of these responsibilities into
separate services. OpenEJB provides a Service Provider Interface (SPI) for
transaction, connectors and security services. These simple and flexible
container-service contracts are based on simple adapters and industry standards
like the Connector API and Java Transaction API (JTA), so it is easy for
service providers to support the SPI and plug directly into OpenEJB. In
addition, services are swappable and are easily configured by the application
server vendor as well as the customer. </span></p>
<a name="architecture"><h3>The Architecture</h3></a>
<a name="arch.overview"><h4>Overview</h4></a>
<p><span class="bodyBlack">
OpenEJB is the first EJB container system that allows developers of an EJB
platform to assemble it from existing products rather than construct it from
scratch. Vendors focus on what they do best while OpenEJB provides the
container to host Enterprise JavaBeans. When plugged into any Java compatible
application server, the result is a complete, yet modular Enterprise JavaBeans
1.1 container system. Through the server-container interface (SCI), an
application server vendor can use the OpenEJB container system to create an
instant and customizable EJB 1.1 platform. Through the service-provider
interface (SPI), primary services may be interchanged to match any target
environment's specific requirements. Figure 1 shows how OpenEJB separates
responsibilities of the application server, container, and primary services.</span></p>
<a name="containers"><h4>The containers</h4></a>
<p><span class="bodyBlack">The OpenEJB container
system provides three robust container types, including stateless and stateful
session-bean containers, and entity-bean containers for both bean- and
container-managed entity beans. These containers are strictly compliant with
the EJB 1.1 specification, and provide the full complement of security and
transaction behaviors to beans. The OpenEJB containers are very lightweight
because they multiplex requests concurrently, requiring less overhead to
service more beans. The containers are also extremely fast because they
introduce virtually no bottlenecks to service requests, allowing thousands of requests
to execute within the container system simultaneously. </span></p>
<a name="primary.services"><h4>The primary services</h4></a>
<p><span class="bodyBlack">OpenEJB defines three
primary services: Transaction, security, and connectors. The containers use the
transaction, security, and connector services while servicing beans and
performing other responsibilities: the transaction service provides the
container with transactional integrity; the security service provides
authorization control; the connectors provides an API for managing resource
connections like JDBC and Java Message Service (JMS).</span></p>
<a name="intravm.server"><h4>The IntraVM server</h4></a>
<p><span class="bodyBlack">OpenEJB includes an
IntraVM server that allows for swift interaction among beans in the same
virtual machine. While respecting the remote semantics required by EJB,
optimizations in method calls from one bean to another provide for very fast
throughput and little or no latency. The IntraVM provides an immediately
available platform for application servers that do not need to support client
access through distributed objects. For example, an existing servlet engine or
web server can use the IntraVM server to integrate the OpenEJB container
systems with very little effort. </span></p>
<a name="customizable"><h4>Customizable</h4></a>
<p><span class="bodyBlack">OpenEJB provides a core
package that is a powerful default implementation of a container system. While
this core is well engineered for performance and efficiency, it is possible to
replace parts of the core system in favor of custom implementations. For
example, the passivation strategy in the stateful container, which currently
writes to a file, can be swapped out in favor of one that writes to a RDMBS or
some other secondary storage. </span></p>
<p><span class="bodyBlack">Developers can also add
custom containers to extend the scope of the container system. A container that
uses JNI to interface with an ERP system, for example, could be integrated with
other core OpenEJB containers. Even the configuration system in OpenEJB, which
currently uses a flexible XML DTD, can be replaced. A proprietary container
assembler could replace the current assembler to build containers from a
database - or even read another vendor's configuration file to load a container
system at runtime. Practically every feature of OpenEJB is replaceable,
providing vendors and customers with unparalleled customization and
flexibility. However, customization is not at all necessary. OpenEJB includes a
powerful core package that makes it an extremely fast container system. </span></p>
<a name="flexible"><h4>Flexible</h4></a>
<p><span class="bodyBlack">The OpenEJB container
system defines lightweight and flexible interfaces that allow vendors to
integrate OpenEJB into their application server products easily. OpenEJB
provides application server vendors without EJB support a fast track to EJB
compliance. OpenEJB also opens up the integration of transaction, security, and
connector services so that vendors and customers alike can choose the services
that are the most appropriate for their EJB platforms. Service providers can
quickly adapt their products to OpenEJB SPI, allowing them to compete with
other vendors on the quality of their service. </span></p>
<a name="open.source"><h3>OpenEJB is Open Source</h3></a>
<a name="license"><h4>The OpenEJB License</h4></a>
<p><span class="bodyBlack">OpenEJB is an open source
software project with a BSD license that is similar to the Apache license.
Although it's a new open source project, OpenEJB already has several platforms
targeted for integration including Apache Tomcat, OpenORB, and OpenJMS.</span></p>
<a name="open.source.advantage"><h4>The open source advantage</h4></a>
<p><span class="bodyBlack">Open source exposes all
the source code of the software to the world, providing significant advantages
to its creators, its customers, and other developers. Unlike proprietary
software, open source products contain no mysteries, no hidden "features."&nbsp;
The support costs are much lower with open source than for a proprietary
product. Customers that encounter anomalous behavior can choose to locate the
exact source of the problem themselves and report it. Most important, open
source encourages customers and other developers to contribute enhancements to
the software, so that an open source product becomes a joint development effort
among its creators, its users, and other vendors. </span></p>
<a name="community"><h4>The open source community</h4></a>
<p><span class="bodyBlack">A community forms around
every open source project, comprising developers and users that employ the
software in commercial and non-commercial environments. If an open source
project is well designed and useful, it can become wildly successful. Typical
and striking examples include Linux, Apache, and Perl, each of which has
enjoyed success in both open source and commercial communities.</span></p>
<a name="open.source.synergy"><h4>The synergy of OpenEJB and open source</h4></a>
<p><span class="bodyBlack">OpenEJB is especially
well suited for open source because its modular design allows it to be
integrated into many different platforms. This flexibility makes OpenEJB the
universal solution for any application server that needs EJB functionality.
OpenEJB represents a revolution in application server design, a view that
application servers' subsystems should be built by organizations that
specialize in those subsystems, then bolted together to create a single
complete platform, turning the potential of modularization into a reality.</span></p>
<p><span class="bodyBlack">Open source code
represents another revolution in software, one that has a special synergy with
modular application server development. Open source exposes the code so that
everyone understands how the software works; modular application server
software like OpenEJB exposes public programming interfaces so that it can be
assembled into an endless variety of platforms. Together, open source and
modular software form an excellent union of two philosophies.</span></p>
<a name="openejb.contract"><h2>The Server-Container Contract</h2></a>
<a name="contract.overview"><h3>Overview</h3></a>
<p><span class="bodyBlack">The Server-Container
Contract defines the separation of responsibilities between the application
server and the OpenEJB container system.&nbsp; The server and container systems
interact exclusively through the interfaces and classes in the org.openejb package[1], which are collectively refereed to
as the Server-Container Interface (SCI).&nbsp; The sever-container contract is
defined by the SCI as well as the policies enumerated in this section of the
OpenEJB specification.</span></p>
<a name="openejb.resp"><h4>OpenEJB Responsibilities</h4></a>
<p><span class="bodyBlack">OpenEJB instantiates a
container system at runtime. The container system is responsible for managing enterprise
beans at runtime according to the information provided in their XML deployment
descriptors[2].&nbsp;
The container system interposes between requests made by the server and
serviced by enterprise beans.&nbsp; The container system interposes to provide transaction,
authorization security, and connector support for beans servicing requests from
the server.&nbsp; The transaction, security, and connector services used during
interposition are those assigned to the container system by the configuration.&nbsp;
</span></p>
<p><span class="bodyBlack">The container system
provides a fast minimally synchronized environment for enterprise beans that is
conformant with the EJB 1.1 specification.</span></p>
<p><span class="bodyBlack">The container system
provides the server with an API (the SCI) for locating the container that hosts
a specific bean deployment and delegating requests to the bean.</span></p>
<a name="server.resp"><h4>Server Responsibilities</h4></a>
<p><span class="bodyBlack">The server is any Java
application that hosts the OpenEJB container system.&nbsp; The server is responsible
for supporting the EJB Client API for distributed clients or some other similar
API (CORBA, DCOM, etc.).&nbsp; The server must provide the stubs, network protocol,
dispatching, and naming services used to locate and communicate requests with
the container system.&nbsp; </span></p>
<a name="contract.api"><h4>The Server-Container Interface</h4></a>
<p><span class="bodyBlack">The server and container
interact through the server-container interface (SCI).&nbsp; The SCI is made up of
the 10 classes and interfaces defined in the org.openejb package.&nbsp; Using the SCI the server
will delegate requests to beans to the container system, which may reply with
return values or exceptions depending on the outcome of the request and the
type of container.</span></p>
<p><span class="bodyBlack">Several classes and
interfaces in the SCI represent a hierarchy for managing and hosting enterprise
beans at runtime. The participants in this hierarchy are described below.</span></p>
<a name="openejb.api"><h5>OpenEJB</h5></a>
<p><span class="bodyBlack">OpenEJB is the root of the container system
hierarchy. It is responsible for loading the configuration information and
manufacturing the containers.&nbsp;
The OpenEJB class is a static singleton that provides access to the
deployments, containers, transaction manager, and security service.</span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
Properties props = new Properties();
...
org.openejb.OpenEJB.init(props);
TransactionManager txMngr = OpenEJB.getTransactionManager();
SecurityService ss = OpenEJB.getSecurityService();
Container [] containers = OpenEJB.containers();
DeploymentInfo [] deployments = OpenEJB.deployments();
</pre></span></td></tr></table>
<p><span class="bodyBlack">One the OpenEJB has been
initialized, it can be used to access the containers, deployments and primary
services.&nbsp; OpenEJB maintains one container system per Java Virtual Machine and
can not be initialized more then once in the life of a process.</span></p>
<a name="container.api"><h5>Container</h5></a>
<p><span class="bodyBlack">The Container manages one or more bean deployments
at runtime. The Container interface provides methods for accessing the
Container's id and the deployments managed by the container (represented by org.openejb.DeploymentInfo
objects). In addition, the container defines the getContainerType() method, which will return Container.ENTITY, Container.STATEFUL, or Container.STATELESS depending
on the bean type managed by the container.</span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
Container cntr = OpenEJB.getContainer("Accounting");
DeploymentInfo [] deployments = cntr.deployments();
DeploymentInfo deployInfo = cntr.getDeployment(someId);
int type = cntr.getContainerType();
</pre></span></td></tr></table>
<p><span class="bodyBlack">The Container interface
has been separated from the RpcContainer in order to support future container
types that are not based on RPC style communications such as the message-driven
bean container in EJB 2.0, which will included in the next release of OpenEJB,
OpenEJB 2.0.</span></p>
<a name="rpc.container.api"><h5>RpcContainer</h5></a>
<p><span class="bodyBlack">The RPC container is used
for SessionBean and EntityBean deployments,
which are accessed via remote procedure calls (RPC) from clients. Its called
the RPC container (RpcContainer)
because it enforces the semantics the Java RMI API, but can be used with any
RPC protocol including JRMP, RMI-IIOP, IIOP, SOAP, and, hypothetically, DCE and
DCOM.&nbsp; The RpcContainers
assume that a call is synchronous and that arguments, return values, and
exceptions will adhere to the Java RMI-IIOP API policies defined by the EJB 1.1
specification -- the actual protocol can be anything.&nbsp; The server is
responsible for translating arguments, return values, and exceptions between
the RpcContainer.invoke()
method and the distributed object protocol used by the server.</span></p>
<p><span class="bodyBlack">The RpcContainer extends the Container interface
and defines one method, invoke( );
The invoke() method
is used by the server to delegate bean requests to the RpcContainer.</span></p>
<p><span class="bodyBlack">
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
RpcContainer rmiCntr =
(RpcContainer)OpenEJB.getContainer("Accounting");
Object retVal =
rmiCntr.invoke(deployID,method,args,null,principal);
</pre></span></td></tr></table>
</span></p>
<a name="deploymentinfo.api"><h5>DeploymentInfo</h5></a>
<p><span class="bodyBlack">The DeploymentInfo represents a unique bean
deployment in the container system.&nbsp; It maintains all deployment information
about the bean that may be useful to the server in determining the behavior and
identity of a specific bean deployment.&nbsp; DeploymentInfo objects are uniquely
identified within the container system by their deployment-id. The
deployment-id can be used in the getDeploymentInfo()
method, defined in both the OpenEJB class and Container interface to obtain a
specific DeploymentInfo object.</span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
Object deployID = deploymentInfo.getDeploymentID();
DeploymentInfo di_1 = OpenEJB.getDeploymentInfo(deployID);
DeploymentInfo di_2 = container.getDeploymentInf(deployID);
If(deployID.equals(di_1) &amp;&amp;
deployID.equals(di_2))
&nbsp;&nbsp;&nbsp; // this condition will always be true
</pre></span></td></tr></table>
<p><span class="bodyBlack">Its expected that most
servers will associate a deployment-id with a remote reference connection,
since the server must supply the deployment-id when invoking the RpcContainer.invoke()
method.&nbsp; Servers can use the DeploymentInfo to obtain information about the
bean as well as obtaining a direct reference to the bean&rsquo;s container.</span></p>
<p><span class="bodyBlack">The deployment-id is
often the same as the JNDI lookup name used by remote clients to access the
bean. This is not a requirement, but can make it direct client requests to the
correct container and DeploymentInfo object.&nbsp; The deployment-id can, however,
be any character string as long as deployment-ids are unique with a container
system.</span></p>
<a name="api.proxyinfo"><h5>ProxyInfo</h5></a>
<p><span class="bodyBlack">An instance of ProxyInfo class represents
a remote reference to a bean in the container system. When a bean method
(create, find, or business methods) is defined as returning a remote reference
to another bean, the container will replace that reference with the ProxyInfo object if its a
local bean. Local beans are those beans deployed in the same container system.</span></p>
<p><span class="bodyBlack">The ProxyInfo object provides information
sufficient for the server to generate a native remote reference that can be
used by the calling client. This native remote reference is implemented using
the distributed protocol used by the server.</span></p>
<a name="api.openejbexception"><h5>OpenEJBException</h5></a>
<p><span class="bodyBlack">This is the base
exception type of the ApplicationException, InvalidateReferenceException and
SystemException. It is never thrown directly by the container system to the
server.</span></p>
<a name="api.applicationexception"><h5>ApplicationException</h5></a>
<p><span class="bodyBlack">An ApplicationException is thrown when invocation
on the bean instance results in a&nbsp; java.rmi.RemoteException
or some type of EJB application exception. The server must propagate the cause
of the ApplicationException to the client.&nbsp; </span></p>
<a name="api.invalidatereferenceexception"><h5>InvalidateReferenceException</h5></a>
<p><span class="bodyBlack">The InvalidateReferenceException is type of ApplicationException that
is thrown when EJB 1.1 policy requires that the server invalidate the client's
remote reference.&nbsp; The InvalidateReferenceException
is only thrown for stateful session beans when an operation results in the
destruction of the bean instance.&nbsp; The server must propagate the cause of the
InvalidateReferenceException (usually a RemoteException) and then make the
clients remote reference inoperable.</span></p>
<a name="api.systemexception"><h5>SystemException</h5></a>
<p><span class="bodyBlack">The org.openejb.SystemException is used to report a
system failure in the container system or one of the service providers
(transaction, security, or connectors).&nbsp; The condition that caused the
exception is considered a partial or complete failure of the container system
that may be isolated to the container or service provider that caused the
exception. </span></p>
<p><span class="bodyBlack">Container may throw a
system exception if an abnormal condition exists while handling server
request.&nbsp; Examples of abnormal conditions include: An I/O error that occurs
passivating stateful bean instances to disk; an invalid deployment-id or call
method is used as an argument to a RpcContainer.invoke() method call.</span></p>
<p><span class="bodyBlack">When a SystemException is thrown,
the server can attempt to recover by re-executing the request, removing the
container from service, or removing the entire container system from service.&nbsp;
The SystemException
wrappers the causal exception which may be evaluated to determine the source of
the failure.&nbsp; For example: If the causal exception is a javax.jta.SystemException the server knows that
the exception was thrown from the transaction service provider. </span></p>
<a name="api.envprops"><h5>EnvProps</h5></a>
<p><span class="bodyBlack">The EnvProps provides a type for standard constants
used when initializing the container system.</span></p>
<a name="rpc.container.contract"><h3>Server-RpcContainer Contract</h3></a>
<p><span class="bodyBlack">The server initializes
the OpenEJB container system at server start-up or before the first bean
request is serviced. Every bean deployment has an id, called the <i>deployment-id</i>,
that is unique within a container system. The server must provide its RPC
clients with a naming service that maps names to deployment-ids associated with
RpcContainers. In many cases the naming service&rsquo;s name binding may be the same
as the deployment-id, but this is not required. When the client performs a name
service lookup, the server will return a home reference; a proxy or stub that
implements the bean's home interface.</span></p>
<p><span class="bodyBlack">The server is responsible
for providing the distributed communication infrastructure (proxies, network
protocol handlers, dispatchers, etc.)&nbsp; for remote references.&nbsp; Every remote
reference provided by the server is associated with a specific deployment-id,
which in turn maps to a specific RpcContainer.&nbsp;
When the client invokes a method on a bean or home reference, the server will
either delegate the request to reference's RpcContainer or service the request itself.</span></p>
<p><span class="bodyBlack">In general, create,
remove, finder, and business methods are delegated to the reference's RpcContainer.&nbsp; The values
returned or exceptions thrown are propagated to the server's clients.&nbsp; The
server itself services all other methods of the EJBHome and EJBObject interfaces because these methods
require the creation of distributed communication artifacts specific to the
server's distributed object protocol&nbsp; (i.e. Handle and EJBMetaData) or that are easily handled by the
server (i.e. EJBObject.isIdentical()
and EJBObject.getPrimaryKey()).</span></p>
<p><span class="bodyBlack">The server delegates all
RPC requests to RPC container using the RpcContainer.invoke() method. The invoke() method will either
return normally or throw an exception.&nbsp; Normal return values are propagated to
client, exceptions are handled according to the exception policies outlined in
section "2.2.1.3 Exceptions". </span></p>
<a name="rpc.invoke.policy"><h4>Invoke Policies</h4></a>
<p><span class="bodyBlack">In general requests by
the client on bean's business methods and the home's create, and find methods
are delegated to the RpcContainer.&nbsp;
The RpcContainer
interface defines the invoke( )
method which represents much of the server-container contract, which is
expressed through parameters, return values, and exceptions that can be thrown
by the invoke method to the server.</span></p>
<a name="rpc.invoke.parameters"><h5>Parameters</h5></a>
<p><span class="bodyBlack">The RpcContainer.invoke( ) method defines declares
five parameters. </span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
public Object invoke(Object deployID,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method callMethod,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object [] args,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object primKey,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object securityIdentity)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws OpenEJBException;
</pre></span></td></tr></table>
<a name="rpc.invoke.deployid"><h6>deployID</h6></a>
<p><span class="bodyBlack">This is the deployment-id
of the bean to be invoked. Every bean deployment has a unique deployment-id
within the scope of a container system.&nbsp; The deployment-id can be used to
obtain the bean's DeploymentInfo object which is used by the container to
select the correct bean deployment to service the method request as well as
providing other information.&nbsp; ( A container can and often does support several
different deployments at the same time.).&nbsp; The deployment-id type is
inconsequential to the container system, but is usually a String or Integer
type. </span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
String deploymentID = &hellip; get deployment id
from request
DeploymentInfo deployment =
OpenEJB.getDeploymentInfo(deploymentID);
RPCContainer container =
(RPCContainer)deployment.getContainer();
container.invoke(deploymentID,callmethod,
args, securityIdentity);
</pre></span></td></tr></table>
<a name="rpc.invoke.callmethod"><h6>callMethod</h6></a>
<p><span class="bodyBlack">This is the java.lang.reflect.Method object
that represents the remote interface (home or remote) method that was invoked
by the client.&nbsp; This parameter is used by the container to determine whether
the method should be delegated directly to the bean or run under a different
method (i.e. create()
is run as ejbCreate()).&nbsp;
In addition, the Method object is used as a key in the container system when
determining the transaction and security attributes that must be applied when
the operating on the bean instance.</span></p>
<a name="rpc.invoke.args"><h6>args</h6></a>
<p><span class="bodyBlack">The args array is the parameter values used by the
client to invoke the remote reference method. The arguments must be indexed in
the array in the same order they are declared on the remote interface method.&nbsp;
Primitive values (int, double, char, etc.) must be
substituted with their primitive wrapper counter parts (Integer, Double, Character, etc.) in the array.&nbsp; The arguments
must be copied and not passed by reference from the client.&nbsp; This will be a
natural occurrence for most distributed object systems since arguments must be marshaled
across the network.&nbsp; Arguments that are remote references must be operational,
meaning that they must implement the remote interface and provide network
access to their respective bean.&nbsp; </span></p>
<a name="rpc.invoke.primkey"><h6>primKey</h6></a>
<p><span class="bodyBlack">The primary key
identifies a unique bean in the container system.&nbsp; For stateful beans the
primary key identifies a unique bean instance that maintains a conversational
state with a specific client.&nbsp; For entity beans the primary key identifies a
unique bean in the database.&nbsp; Stateless session beans do not use a primary key,
so the primKey parameter will be null for requests on stateless beans.&nbsp; The primKey is usally null for invocations
servicing home interface methods -- home references don't have a primary key.&nbsp;
The exception is EJBHome remove methods for which the server must provide the
primary key of the bean (stateful or entity) that is to be removed.</span></p>
<a name="rpc.invoke.securityidentity"><h6>securityIdentity</h6></a>
<p><span class="bodyBlack">The securityIdentity is the security identity
representing the client.&nbsp; The server is responsible for providing the proper
object for the container systems designated security service. The type and
implementation of the securityIdentity
object is immaterial to the container. It's assumed that the security service
used by the container will know how to use it.</span></p>
<p><span class="bodyBlack">For example, if the
container's profile specifies security service provider that uses SSL
authentication, then the proper SSL credential may be passed as the securityIdentity
parameter.&nbsp; If the security service provider uses Kerberos then the proper
Kerberos token may be passed as the securityIdentity&nbsp; parameter.</span></p>
<a name="rpc.invoke.returnvalues"><h5>Return Values</h5></a>
<p><span class="bodyBlack">The RpcContainer.invoke() method returns an Object
type.&nbsp; The value of the return depends on the expected return type of the
remote method that was invoked; the declared return type of the home or remote
interface.&nbsp; </span></p>
<a name="returnvalues.void"><h6>void</h6></a>
<p><span class="bodyBlack">If the remote interface
method returns a void, the invoke(
) method will return a null value.&nbsp; The remote reference will then
return void.</span></p>
<a name="returnvalues.primitives"><h6>primitive types</h6></a>
<p><span class="bodyBlack">If the remote interface
method returns a single primitive value (int, double, char, etc.), the invoke() method will return the corresponding
primitive wrapper (Integer,
Double, Character, etc.) object.&nbsp;
The remote reference will then return the primitive value of the wrapper
object.</span></p>
<a name="returnvalues.serializable"><h6>Serializable types</h6></a>
<p><span class="bodyBlack">If the remote interface
method returns a serializable type, the invoke() method will return an object of that
type.&nbsp; The remote reference returns a copy of the serializable object.</span></p>
<p><span class="bodyBlack">The exception is java.lang.String and
primitive wrapper types (Integer,
Double, Character, ect.),&nbsp; which
are immutable and need not be copied.</span></p>
<a name="returnvalues.arrays"><h6>Array Value types</h6></a>
<p><span class="bodyBlack">If the remote interface
method returns an array, the invoke()
method will return an array of that type.&nbsp; The remote reference returns a
complete copy of the array including the individual elements.</span></p>
<a name="returnvalues.remote.references"><h6>Remote References</h6></a>
<p><span class="bodyBlack">If the remote interface
method returns a remote reference, the invoke() method will either return ProxyInfo object or the
actual remote reference.&nbsp; ProxyInfo
objects are returned for local beans, which are beans managed within the
container system.&nbsp; Remote references are returned by for non-local beans, which
are beans managed by a different container system or a different EJB vendor
(Weblogic, WebSphere, etc.).</span></p>
<p><span class="bodyBlack">If the method called is a
create or single object find method, the invoke()&nbsp; method will return the ProxyInfo that represents
the created or found bean. If a business method returns a remote reference to a
local bean, the container will return a ProxyInfo object for that bean. The server
then, must generate the remote reference based on the ProxyInfo and returned that reference to the
client. </span></p>
<p><span class="bodyBlack">The ProxyInfo object provides information
sufficient for the server to generate a remote reference for the local bean
including the remote interface to implement (remote or home), the
deployment-id, the primary key of the bean, and the a reference to the bean's
container.</span></p>
<p><span class="bodyBlack">If the bean returns a
remote reference to a non-local bean, the container will return that same
remote reference to the server. The assumption is that the remote reference
from the non-local bean (different container system or vendor) is serializable,
so otherwise can be transferred between address spaces and remain operational.&nbsp;
Problems can occur when the distributed object protocol used by the sever is
incompatible with the non-local bean reference's implementation.</span></p>
<a name="exceptions"><h5>Exceptions</h5></a>
<p><span class="bodyBlack">There are three possible
exceptions that can be thrown by the invoke() method: ApplicationException, SystemException, or the InvalidateReferenceException.&nbsp; </span></p>
<a name="applicationexception"><h6>ApplicationException</h6></a>
<p><span class="bodyBlack">An ApplicationException is thrown when invocation
on the bean instance results in a&nbsp; java.rmi.RemoteException
or some type of EJB application exception. The server must propagate the cause
of the ApplicationException
to the client.&nbsp; When an ApplicationException
is thrown, the cause is considered to be normal; it does not represent a system
failure or require invalidation of the remote reference. The cause should be
propagated to the client but no other action need be taken by the server.</span></p>
<p><span class="bodyBlack">When a bean method throws
a custom application exception from a business methods or a standard
application exception (CreateException,
ObjectNotFoundException,
etc.) from a standard business method (ejbCreate, ejbFind, etc.), the container will catch the
exception and re-throw it wrapped in an ApplicationException to the server.</span></p>
<p><span class="bodyBlack">Under some circumstances,
a RemoteException may
occur while delegating a request to the bean instance. Examples include: A
security authorization violation (the client is not authorized to access the
bean method);&nbsp; An attempt to propagate a transaction to a bean method declared
with the Never
transaction attribute; An attempt to perform a loopback on an entity bean that
is declared as non-reentrant.&nbsp; In these cases the RemoteException will be wrapped in a
ApplicationException by the container and thrown to the server from the invoke() method.&nbsp; The
server must treat the RemoteException
as it would any custom application exception; the RemoteException should be propagated to the
client, but no other action need be taken by the server.</span></p>
<a name="invalidatereferenceexception"><h6>InvalidateReferenceException</h6></a>
<p><span class="bodyBlack">The InvalidateReferenceException is type of ApplicationException that
is thrown when EJB 1.1 policy requires that the server invalidate the client's
remote reference.&nbsp; The InvalidateReferenceException
will nest a RemoteException
or standard application exception (i.e. ObjectNotFoundException) that must re-thrown to
the client by the bean reference. The InvalidateReferenceException is only thrown for
stateful session beans when an operation results in the destruction of the bean
instance.&nbsp; Examples include:&nbsp; An EJBException
is thrown by a stateful bean method (business method or standard callback
method) and the instance is evicted; A client attempts to invoke a method on a
stateful bean object that no longer exists.</span></p>
<p><span class="bodyBlack">When the invoke()&nbsp; method throws an ApplicationException the
server must: First throw the nested (cause) exception to the client; Second,
invalidate the reference so that any subsequent method invoked on the reference
immediately throw a RemoteException.&nbsp;
The reference is made inoperable.</span></p>
<a name="systemexception"><h6>SystemException</h6></a>
<p><span class="bodyBlack">A SystemException is
thrown by the invoke() method when a partial failure of the container or one of
the service providers (transaction, security, connectors) has occurred while
servicing the method. Conditions that cause a SystemException and server responsibilities are
covered in more detail in Section 2.4: SystemException.</span></p>
<p><span class="bodyBlack">A SystemException represents a serious error in
the container system. It should be assumed if this exception is thrown that the
container system is unstable and appropriate action by the server should be
taken.</span></p>
<a name="ejbobject"><h4>The EJBObject</h4></a>
<p><span class="bodyBlack">The EJBObject is
implemented by server specific stub that acts as a remote reference to a
corresponding bean in a RpcContainer.&nbsp; The EJBObject stub must implement both
the javax.ejb.EJBObject
interface as well as the remote interface (and all its super types) defined by
the bean developer.&nbsp; </span></p>
<p><span class="bodyBlack">When an EJB client
creates or finds a bean from a EJBHome reference, the server is responsible for
returning a remote reference to that bean. The remote reference, the EJBObject,
is implemented according to the server's distributed object protocol and is
bound to its bean's RpcContainer at the server.&nbsp; How this is accomplished is up
to the server, but it is expected that servers will maintain a mapping between
the EJBObject's network connection or logical thread, and the correct
RpcContainer using the deployment-id.&nbsp; For stateful and entity beans, the
EJBObject reference is mapped to a specific bean instance within a container
using the deployment-id and primary key.</span></p>
<a name="remote.interface"><h5>Remote Interface Methods</h5></a>
<p><span class="bodyBlack">The remote interface
methods, those business methods defined by the bean developer in the remote
interface, are delegated to the invoke()
method of the appropriate RpcContainer
(the container that services the bean deployment represented by EJBObject).&nbsp; Invocations on
the EJBObject stub
are transmitted from client to the server (using the servers distributed object
protocol) and then delegated to the appropriate RpcContainer.</span></p>
<a name="ejbobject.interface"><h5>EJBObject Interface Methods</h5></a>
<p><span class="bodyBlack">Except for the remove( ) method, all
EJBObject interface methods are implemented by the server.&nbsp; (The remove( ) method is handled
by the OpenEJB RpcContainer via the invoke( ) method.)&nbsp; The EJBObject methods are dependent on
server specific conventions and distributed object protocol, so the responsibly
for implementing these methods falls on the server. </span></p>
<a name="getEJBHome"><h6>getEJBHome</h6></a>
<p><span class="bodyBlack">The getEJBHome() method is handled by the server
which will need to return an application server implementation of the EJBHome
stub implementing the appropriate home interface to the client.</span></p>
<a name="getHandle"><h6>getHandle</h6></a>
<p><span class="bodyBlack">The getHandle( ) method is implemented by the
application server.&nbsp; The Handle class needs to be serializable, so that it can
be written to file or stream.&nbsp; The Handle implementation must be able to
re-connect to the server after it is deserialized using the server's
distributed object protocol, and return an EJBObject stub for the appropriate
bean.</span></p>
<a name="getPrimaryKey"><h6>getPrimaryKey( )</h6></a>
<p><span class="bodyBlack">The server may choose to
maintain a reference to the primary key in the stub, or to maintain it at the
server.&nbsp; Session beans do not expose their primary keys, so the application
server will need to throw a RemoteException when this method is invoked on
session EJBObject stubs.</span></p>
<a name="isIdenticial"><h6>isIdenticial</h6></a>
<p><span class="bodyBlack">The isIdenticial(EJBObject obj) method is
implemented by the server.&nbsp; The application server should compare container and
deployment-ids for an exact match.&nbsp;&nbsp; In addition, the identity (primary key)
for entity and stateful session beans must match as well.&nbsp; The primary key and
other identifiers may be maintained in the EJBObject stubs or on the server.</span></p>
<a name="remove"><h6>remove</h6></a>
<p><span class="bodyBlack">The remove( ) method is
delegated by the server to the invoke(
) method of the proper RpcContainer.&nbsp; When invoked on an EJBObject
stub for a stateless bean, the server doesn't not need to delegate the
invocation to the container -- EJBObject.remove( ) invocations are not handled
by the stateless container. </span></p>
<p><span class="bodyBlack">Once a remove( ) method has been
processed, the server should attempt to invalidate all the EJBObject stubs of
the bean that was removed, so that subsequent invocations on that EJBObject
stub result in javax.ejb.ObjectNotFoundException
being thrown to the client. Subsequent requests by server on behalf of the
removed bean will result in the RpcContainer
throwing a&nbsp; org.openejb.ApplicationException
that wraps a javax.ejb.ObjectNotFoundException.</span></p>
<a name="ejbhome"><h4>The EJBHome</h4></a>
<p><span class="bodyBlack">The EJBHome is implemented
by server specific stub that acts as a remote reference to a corresponding
deployment in a RpcContainer.&nbsp; The EJBHome stub must implement both the javax.ejb.EJBHome interface
as well as the home interface (and all its super types) defined by the bean
developer.&nbsp; </span></p>
<p><span class="bodyBlack">When the client uses a
naming service to locate a bean's EJBHome reference, the server is responsible
for returning a remote reference to that bean. The home reference, the EJBHome,
is implemented according to the server's distributed object protocol and is
bound to its bean's RpcContainer at the server.&nbsp; How this is accomplished is up
to the server, but it is expected that servers will maintain a mapping between
the EJBHome's network connection or logical thread, and the correct RpcContainer
using the deployment-id.&nbsp; In some cases the deployment-id and the lookup name
may be the same value, but this is not required and is considered a server
specific option.</span></p>
<a name="home.interface"><h5>Home Interface Methods</h5></a>
<p><span class="bodyBlack">The home interface
methods, those methods defined by the bean developer in the home interface, are
delegated to the invoke()
method of the appropriate RpcContainer
(the container that services the bean deployment represented by EJBHome).&nbsp; Invocations on
the EJBHome stub are
transmitted from client to the server (using the servers distributed object
protocol) and then delegated to the appropriate RpcContainer.</span></p>
<p><span class="bodyBlack">In the case of home
interface methods, a null
value must be passed as the primary key argument in the RpcContainer.invoke() method.&nbsp; Home interface
methods are not specific to one bean instance and so have no primary key
associated with method requests. The only exception to this is the EJBHome
remove methods which are discussed in more detail in section 2.2.3.2.</span></p>
<p><span class="bodyBlack">When a home interface create method is delegated
to the RpcContainer
the return value will always be a ProxyInfo
object describing the remote reference that should be returned to the client.&nbsp;
The remote reference is a distributed object stub implemented according to the
server distributed object protocol. </span></p>
<p><span class="bodyBlack">When a single-value find method (i.e. findByPrimaryKey() ) is
delegated to the RpcContainer
a single ProxyInfo
object will be returned, the same as with the create methods.&nbsp; When a multi-value find method is delegated to
the RpcContainer, a java.util.Collection of ProxyInfo objects is
returned to the server. The server is then responsible for returning a Collection or Enumeration of remote
references to the client. The collection type returned to the client depends on
how the find method
was declared.</span></p>
<a name="ejbhome.interface"><h5>EJBHome Interface Methods</h5></a>
<p><span class="bodyBlack">Except for the remove( ) method, all EJBHome interface methods
are implemented by the server.&nbsp; (The remove( ) method is handled by the OpenEJB
RpcContainer via the invoke( )
method.)&nbsp; The EJBHome
methods are dependent on server specific conventions and distributed object
protocol, so the responsibly for implementing these methods falls on the
server. </span></p>
<a name="getEJBMetaData"><h6>getEJBMetaData</h6></a>
<p><span class="bodyBlack">The getEJBMetaData( ) method is implemented by the
application server.&nbsp; The EJBMetaData
class needs to be serializable, so that it can be written to file or stream.
Using the deployment-id, the server can lookup the DeploymentInfo object for that bean, and use it
to populate the EJBMetaData
object.&nbsp; In addition, the EJBMetaData
implementation must be able to re-connect to the server after it is
deserialized using the server's distributed object protocol, and return an EJBHome stub from the EJBMetaData.getEJBHome( )
method.</span></p>
<a name="getHomeHandle"><h6>getHomeHandle</h6></a>
<p><span class="bodyBlack">The getHomeHandle( ) method is implemented by the
application server.&nbsp; The HomeHandle
class needs to be serializable, so that it can be written to file or stream.&nbsp;
The HomeHandle
implementation must be able to re-connect to the server after it is
deserialized using the server's distributed object protocol, and return an
EJBHome stub for the appropriate bean.</span></p>
<a name="remove"><h6>remove</h6></a>
<p><span class="bodyBlack">The remove( ) methods are delegated by the server
to the invoke( )
method of the proper RpcContainer.&nbsp;
When invoked on a EJBHome
stub for a stateless bean, the server doesn't not need to delegate the
invocation to the container -- EJBHome.remove(
) invocations are not handled by the stateless container &ndash; but
doing so will not cause an error. </span></p>
<p><span class="bodyBlack">Once a remove( ) method has been
processed, the server should attempt to invalidate all the EJBObject stubs of the bean that was removed,
so that subsequent invocations on that EJBObject stub result in javax.ejb.ObjectNotFoundException being thrown
to the client. Subsequent requests by server on behalf of the removed bean will
result in the RpcContainer
throwing a&nbsp; org.openejb.ApplicationException
that wraps a javax.ejb.ObjectNotFoundException.</span></p>
<a name="api.service.provider"><h2>The Service Provider Interface</h2></a>
<a name="connector.support"><h3>Connector Support</h3></a>
<p><span class="bodyBlack">Included in the service
provider interface of OpenEJB is the Connector API.&nbsp; The Connector API is a standard
J2EE API that defines a contract between the &ldquo;application server&rdquo; and resource
connectors.&nbsp; Resource connectors are technology specific APIs for accessing
backend systems like relational databases, messaging services, and ERP
systems.&nbsp; The most familiar resource APIs are JDBC and JMS.&nbsp; It is the
responsibility of the &ldquo;application server&rdquo; to manage the pooling and
application of transactions and security services to resource connections used
by enterprise beans.&nbsp; It's the responsibility of the connectors to provide
physical resource connections and the facilities for manufacturing those
connections.&nbsp; The Connector API specifies how &ldquo;application server&rdquo; and the
connectors interact to manage resource connections.&nbsp; </span></p>
<p><span class="bodyBlack">In the case of OpenEJB
the role of the &ldquo;application server&rdquo; -- as defined by the Connector API
specification -- is fulfilled by the OpenEJB container system.&nbsp; OpenEJB
provides a mechanism for declaring connectors and their connection managers in
the XML configuration file.&nbsp; OpenEJB also provides connection managers with
access to the appropriate transaction and security service at runtime through a
standard JNDI name space. </span></p>
<p><span class="bodyBlack">A connection manager is
responsible for managing resource connections according the contracts defined
in the Connector API.&nbsp; This includes pooling and sharing connections as well as
managing the transaction and security contexts of connection at runtime.&nbsp;&nbsp;
Connection managers implement the javax.resource.spi.ConnectionManager
interface defined in the Connector API.&nbsp;&nbsp;&nbsp; </span></p>
<p><span class="bodyBlack">A resource connection
(a.k.a. connector) is responsible for providing physical connections to a
backend resource such as a relational database or enterprise messaging system.&nbsp;
A connector must implement the SPI contracts defined by the Connector API
specification in addition to a technology specific API.&nbsp; For example, a JDBC
connector will implement the Connector SPI as well as the JDBC API. Similarly,
a JMS connector will implement the Connector SPI and the JMS API.&nbsp; The
Connector SPI is used by the connection manager to mange the physical resource
connections -- independent of the type of backend resource accessed by the
connector.&nbsp; The technology specific API is used by enterprise beans to work
directly with the backend resource accessed by the connector.&nbsp; For example, an
enterprise bean will use the JDBC API to query, update, and delete records in a
relational database system.</span></p>
<p><span class="bodyBlack">The advantage of the
Connector API is that it allows any Connector compliant resource to work with
any Connector compliant application server.&nbsp; A vendor who creates a connector
for a specific backend resource can be assured that their product will work
with any application server that supports the Connector API.&nbsp; Before the
introduction of the Connector API, organizations were limited to the resource
connections supported by their application server.&nbsp; The Connector API largely
eliminates this limitation. If your application server is complaint with the
connector API, it should automatically support any existing and newly defined
connectors.</span></p>
<p><span class="bodyBlack">OpenEJB takes this
portability a step further by making the connection managers plugable.&nbsp; In most
application servers, the vendor will offer one or more connection manager
options, but the selection of connection managers are fixed and proprietary --
they are built into the application server.&nbsp; OpenEJB, on the other hand, allows
any third party to define a connection manager that can easily be plugged into
OpenEJB and used at runtime to manage connectors.&nbsp;&nbsp; The connection manager
defined by the third party is responsible for pooling connections and
interacting with connectors according to the Connector API.&nbsp; OpenEJB is
responsible for providing the connection manager with access to a JTA
TransactionManager and the security service.&nbsp; In addition, OpenEJB provides
enterprise beans with access to connectors through their JNDI environment
naming context (ENC).&nbsp; The bean uses only the resources technology specific API
and is not aware of the connector API, which is only used by the connection
manager.</span></p>
<p><span class="bodyBlack">While developing
connectors and connection managers is not trivial, plugging third party
connectors and connection managers into OpenEJB is very easy.&nbsp; Both connectors
and connection managers are declared in the facilities section of OpenEJB's XML
configuration file.&nbsp; The following example shows that multiple connectors can
be assigned to the same connection manager.&nbsp; In this case the OpenEJB JDBC
Connector and a JMS connector provide by the Acme corporation are assigned to
the Connection manager provided by Blue Sky corporation.</span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
&lt;connectors&gt;
&lt;connector&gt;
&nbsp;&nbsp;&nbsp; &lt;connector-id&gt;<b>OrdersDatabase</b>&lt;/connector-id&gt;
&nbsp;&nbsp;&nbsp; &lt;connection-manager-id&gt;<b>LocalShared</b>&lt;/connection-manager-id&gt;
&nbsp;&nbsp;&nbsp; &lt;managed-connection-factory&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&lt;class-name&gt;org.openejb.resource.jdbc.JdbcManagedConnectionFactory
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/class-name&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;properties&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
&lt;property-name&gt;setJdbcDriver&lt;/property-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
&lt;property-value&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/property-value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
&lt;property-name&gt;setJdbcUrl&lt;/property-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
&lt;property-value&gt;jdbc:odbc:orders&lt;/property-value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/properties&gt;
&nbsp;&nbsp;&nbsp; &lt;/managed-connection-factory&gt;&nbsp;&nbsp;
&lt;/connector&gt;
&lt;connector&gt;
&nbsp;&nbsp;&nbsp; &lt;connector-id&gt;<b>InventoryTopic</b>&lt;/connector-id&gt;
&nbsp;&nbsp;&nbsp; &lt;connection-manager-id&gt;<b>LocalShared</b>&lt;/connection-manager-id&gt;
&nbsp;&nbsp;&nbsp; &lt;managed-connection-factory&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&lt;class-name&gt;com.acme.jms.TopicManagedConnectionFactory
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/class-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;properties&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
&lt;property-name&gt;URL&lt;/property-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;property-value&gt;jms:acme.com/mytopic&lt;/property-value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/properties&gt;
&nbsp;&nbsp;&nbsp; &lt;/managed-connection-factory&gt;&nbsp;&nbsp;
&lt;/connector&gt;
&lt;connection-manager&gt;
&nbsp;&nbsp;&nbsp; &lt;connection-manager-id&gt;<b>LocalShared</b>&lt;/connection-manager-id&gt;
&nbsp;&nbsp;&nbsp; &lt;class-name&gt;
&nbsp;&nbsp;&nbsp; com.blue-sky.openejb.ConnectionManager
&nbsp;&nbsp;&nbsp; &lt;/class-name&gt;
&lt;/connection-manager&gt;
&lt;/connectors&gt;
</pre></span></td></tr></table>
<p><span class="bodyBlack">Connectors can be
assigned to any one of several connection managers. Connectors can be assigned
to any one of several connection managers. For example, there could be four
connectors declared and two connection managers. Two of the connectors are
assigned to one connection manager, while the other two are assigned to the
other connection manager.</span></p>
<p><span class="bodyBlack">Enterprise beans access
connectors as resources through their JNDI ENC.&nbsp; The connector-id used in the
deceleration of a resource is mapped directly to connector-id of a connector in
the facilities section.&nbsp; In the below example, the enterprise bean declares two
resources whose connector-id elements
map to connectors shown in the previous example.</span></p>
<p><span class="bodyBlack">
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
&lt;entity-bean&gt;
&nbsp;&nbsp;&nbsp;
&lt;display-name&gt;EmployeeEJB&lt;/display-name&gt;
&nbsp;&nbsp;&nbsp;
&lt;ejb-deployment-id&gt;111111&lt;/ejb-deployment-id&gt;
&nbsp;&nbsp;&nbsp;
&lt;home&gt;org.openejb.test.beans.EmployeeHome&lt;/home&gt;
&nbsp;&nbsp;&nbsp;
&lt;remote&gt;org.openejb.test.beans.Employee&lt;/remote&gt;
&nbsp;&nbsp;&nbsp;
&lt;ejb-class&gt;org.openejb.test.beans.EmployeeBean&lt;/ejb-class&gt;
&nbsp;&nbsp;&nbsp;
&lt;primary-key&gt;java.lang.Integer&lt;/primary-key&gt;
&nbsp;&nbsp;&nbsp; &lt;jndi-enc&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resource-ref&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;res-ref-name&gt;jdbc/orders&lt;/res-ref-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>&lt;connector-id&gt;OrdersDatabase&lt;/connector-id&gt;</b>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/resource-ref&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resource-ref&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;res-ref-name&gt;jms/inventoryTopic&lt;/res-ref-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;res-type&gt;javax.jms.TopicConnectionFactory&lt;/res-type&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>&lt;connector-id&gt;InventoryTopic&lt;/connector-id&gt;</b>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/resource-ref&gt;
&nbsp;&nbsp;&nbsp; &lt;/jndi-enc&gt;
&lt;/entity-bean&gt;
</pre></span></td></tr></table>
</span></p>
<a name="connector.notes"><h4>Note on January 4, 2001</h4></a>
<p><span class="bodyBlack">The Connector API is near
completion but is not yet in its final release.&nbsp; As a result there are no
connectors currently available.&nbsp; While its believed that vendors will quickly
release a cornucopia of connectors following the specification's final release,
the OpenEJB project provides an interim solution: a JDBC connector that can be
used with any JDBC driver. The JDBC connector is packaged under org.openejb.resource.jdbc.
It can be used to wrapper any JDBC driver and make it Connector compliant
(limited).&nbsp; The OpenEJB JDBC connector is currently limited to local
transactions (see Connector specification) and does not provide support for the
XA interfaces and 2-phase commit.&nbsp; This is likely to change in the coming
months.&nbsp; In the mean time, organizations can use the OpenEJB JDBC connector to
access any JDBC compliant database within a local transaction.&nbsp; </span></p>
<p><span class="bodyBlack">OpenEJB also provides a
connection manager, the org.openejb.resource.SharedLocalConnectionManager,
that can be used to manage any connector that supports local transactions.&nbsp; In
addition the SharedLocalConnectionManager
supports connection sharing, so that components in a chain of execution will
automatically share the same physical connection and local transaction.&nbsp; This
makes it possible to support a transaction for a single resource that spans
several components in the same unit-of-work.&nbsp; </span></p>
<p><span class="bodyBlack">For example, bean A calls
bean B which calls bean C.&nbsp; All three beans access the same JDBC resource from
their JNDI ENC (the res-id is the same).&nbsp; With connection sharing bean B and C
will use the same physical JDBC connection used by bean A. When the
unit-of-work is complete and all the beans have completed their work, the
transaction on the JDBC connection will be committed.&nbsp; All the work preformed
on that physical connection by each of the beans is committed or rollback
together; its atomic.&nbsp; However, connection sharing does not allow different
resources to be enrolled in the same local transaction. If for example, beans
A, B, and C all access JDBC and JMS resources, then the JDBC work will be
committed together and the JMS work will be committed together, but the JDBC
and JMS work will be committed separately.&nbsp; If the JDBC commit fails, the JMS
commit will still be executed.&nbsp; That's the limitation of a shared local
connection manager. A connection manager that supports 2-phase commit would
ensure that these different resources succeed or fail together.&nbsp; Its likely
that a connection manager that supports 2-phase commit will be provided by
OpenEJB or some third party in the future.</span></p>
<p><span class="bodyBlack">From a developers stand
point the connectors are a non-issue.&nbsp; The developer simply declares which
connectors are used with which connection managers and maps the connectors as
resources enterprise bean's JNDI ENC.&nbsp;&nbsp; Its our hope that others will consider
developing connection managers that can be used with OpenEJB.&nbsp; Over the coming
weeks the OpenEJB-ConnectionManager interface will be refined. Currently,
OpenEJB provides connector managers with access to the TransactionManager used
by the bean requesting access to a resource. </span></p>
<a name="The Core OpenEJB Implementation"><h2>The Core OpenEJB Implementation</h2></a>
<a name="Vendor Interoperability"><h2>Vendor Interoperability</h2></a>
<a name="customization"><h2>OpenEJB Customization</h2></a>
<a name="factory"><h3>The OpenEJB Factory</h3></a>
<p><span class="bodyBlack">The OpenEJB class manufactures an instance of OpenEJB with a complete
container system that is ready to accept bean requests. Essentially, the server
will use the static init( )
method of the OpenEJB
class to bootstrap a container system.&nbsp; The Properties object passed as an
argument to the init( )
method is combined with the System properties and passed to the constructor of
an OpenEJB instance.&nbsp; </span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
Properties props = new Properties();
...
OpenEJB ejb =
org.openejb.OpenEJB.init(props);
</pre></span></td></tr></table>
<p><span class="bodyBlack">The OpenEJB instance is responsible initiating the
construction of container system by locating the correct Assembler and providing it with access to
configuration information. The Assembler is responsible for constructing every
artifact of the container system and preparing it to service bean requests
based on configuration information.&nbsp; The type of Assembler and the source of
the configuration information can be identified through properties, which can
be declared in the Properties argument or in the system class properties. </span></p>
<p><span class="bodyBlack">The Assembler property
uses the property name "org/openejb/assembler_class".
This property name is bound to the fully qualified class name of the Assembler
class used to build the OpenEJB container system. The default implementation
is, which is used if an Assembler property is not specified, is the org.openejb.core.conf.Assembler.&nbsp;
The Assembler is responsible for constructing the entire container system using
the configuration information.&nbsp; </span></p>
<p><span class="bodyBlack">The configuration source
property uses the property name "org/openejb/configuration_source". This
property identifies the source of the configuration information used to build
the container system. The configuration source may be a local file, remote
location, a database table, etc.&nbsp; The configuration information itself can take
any form as long as it works with the named Assembler.&nbsp; The default Assembler expects a XML
file that is located on the local hard drive and conforms to the <i>openejb_config.dtd</i>.</span></p>
<p><span class="bodyBlack">The Assembler and
configuration source property names are conveniently declared as static fields
in org.openejb.EnvProps class. </span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
package org.openejb;
public class EnvProps {
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; public final static String
CONFIGURATION = "org/openejb/configuration_source";
&nbsp;&nbsp;&nbsp; public final static String ASSEMBLER
= "org/openejb/assembler_class";
}
</pre></span></td></tr></table>
<p><span class="bodyBlack">If the core OpenEJB implementation
is to be used, the&nbsp; EnvProps.ASSEMBLER
property should not be declared since the default is to use the core Assembler
class.&nbsp; The EnvProps.CONFIGURATION
property, however, must be set to the file location of the XML configuration
file on the local hard drive. </span></p>
<p><span class="bodyBlack">It's possible to develop
and use a custom Assembler class.&nbsp; This would be useful if custom containers or
other artifact are needed that can not be constructed by the default core
Assembler.&nbsp; Some vendors may, for example, want to use a configuration schema
that is different then the XML schema used with OpenEJB's core library. This
would require a new or modified Assembler.&nbsp;&nbsp; If a custom Assebler is needed, it
can be specified in the properties along with its custom configuration.&nbsp; For
example, an assembler might be constructed that can build an container system
off of a Weblogic properties files. </span></p>
<table width="440" cellspacing="0" cellpadding="0" border="0"><tr><td bgcolor="#e0e0e0"><span class="code-block"><pre>
Properties props = new Properties();
props.addProperty(EnvProps.ASSEMBLER,
"com.acme.openejb.weblogic_assembler");
props.addProperty(EnvProps.CONFIGURATION,
"c://openejb/welogic.props");
org.openejb.OpenEJB.init(props);
</pre></span></td></tr></table>
</td><td align="left" valign="top" height="5" width="120">
&nbsp;
</td></tr><tr height="5"><td align="left" valign="top" bgcolor="#7270c2" height="5" width="20">&nbsp;</td><td valign="top" bgcolor="#7270c2" height="5" width="95">&nbsp;</td><td align="left" valign="top" bgcolor="#a9a5de" height="5" width="7">&nbsp;</td><td align="left" valign="top" height="5" width="40">&nbsp;</td><td align="left" valign="top" height="5" width="120">&nbsp;</td></tr><tr><td align="left" valign="top" bgcolor="#7270c2" height="5" width="20">&nbsp;</td><td align="left" valign="top" bgcolor="#7270c2" width="95">&nbsp;</td><td align="left" valign="top" bgcolor="#a9a5de" width="7"><img border="0" height="25" width="1" src="images/dotTrans.gif"></td><td align="left" valign="top" width="40"><img border="0" height="25" width="1" src="images/dotTrans.gif"></td><td align="left" valign="top" width="120">&nbsp;</td></tr><tr height="5"><td align="left" valign="bottom" bgcolor="#7270c2" height="100%" rowspan="2" width="20"><img border="0" height="125" width="20" src="images/stripes1.gif"></td><td align="left" valign="bottom" bgcolor="#7270c2" height="100%" rowspan="2" width="95"><img border="0" height="125" width="105" src="images/stripe105.gif"></td><td align="left" valign="top" bgcolor="#a9a5de" height="100%" rowspan="2" width="7">&nbsp;</td><td align="left" valign="top" height="100%" width="40">&nbsp;</td><td align="left" valign="top" height="100%" width="120">&nbsp;</td></tr><tr height="5"><td align="left" valign="top" height="25" width="40">&nbsp;</td><td align="left" valign="bottom" height="25" width="430"><br><br><img height="3" width="430" border="0" src="images/line_light.gif"><br><p></p><span class="bodyGrey"><small><notice>
OpenEJB is a trademark of the OpenEJB Group.
Java, EJB, JDBC, JNDI, JTA, Sun, Sun Microsystems are trademarks or registered
trademarks of Sun Microsystems, Inc. in the United States and in other
countries. XML, XML Schema, XSLT and related standards are trademarks or registered
trademarks of MIT, INRIA, Keio or others, and a product of the World Wide Web
Consortium. All other product names mentioned herein are trademarks of their respective
owners.
</notice><br>&nbsp;<br></small></span><p></p>
&nbsp;
</td><td align="left" valign="top" height="25" width="120">&nbsp;</td></tr></table></body></html>