| <?xml version="1.0"?> |
| <document url="http://openejb.sf.net/embedded.xml"> |
| <properties> |
| <title>Deployment IDs</title> |
| </properties> |
| <body> |
| |
| <section title="What is a Deployment ID?" ref-id="definition"> |
| <p> |
| Every bean deployed in OpenEJB has a unique deployment-id that identifies it |
| within the scope of the entire container system. The server and container system |
| refer beans at run-time using the bean's deployment id. |
| </p> |
| |
| <p> |
| This deployment id is much like the <ejb-name> element of the ejb-jar.xml |
| , with one very important difference. The <ejb-name> is only required to be |
| unique within the scope of the ejb-jar.xml in the bean's jar. The deployment id is |
| required to be unique across all beans and jars in OpenEJB. This is a subtle, but |
| important, distinction. |
| </p> |
| |
| <p> |
| Remember that the EJB specification was designed so that enterprise beans could be |
| create, packaged, and sold by vendors (EJB Providers). Furthermore, users should be able |
| to buy a packaged set of beans (a jar with an ejb-jar.xml in it) and deploy it into an |
| EJB Container without modification. |
| </p> |
| |
| <p> |
| Let's consider this, what happens if two vendors each sell a package (jar) |
| that contains a bean with the <ejb-name> PurchaseOrder? Both are completely different |
| in terms functionality and are different beans in every other respect. The EJB spec says, this |
| is fine, ejb-names only have to unique within the jar and that jar's ejb-jar.xml file. It's |
| redictulous to excpect EJB Providers to call each other up and ask, "Are you already using the |
| name 'PurchaseOrder' in your jar?" Remember that the EJB specification was designed so that enterprise beans could be |
| create, packaged, and sold by vendors (EJB Providers). Furthermore, users should be able |
| to buy a packaged set of beans (a jar with an ejb-jar.xml in it) and deploy it into an |
| EJB Container without modification. This is all fine and dandy, but it still leaves it up |
| to the EJB Container/Server providers to settle the difference. |
| </p> |
| |
| <p> |
| OpenEJB solves this with the OpenEJB-specific deployment id. By requiring that |
| each bean deployed into OpenEJB has a unique name, we can guarantee that we are always |
| refering to the right bean at all times. Futhermore, it allows you to deploy |
| different versions of the same package several times in the same container system, each |
| time giving the beans new deployment ids. |
| </p> |
| |
| <p> |
| If you're lazy --as any truly great programmer should be-- and don't want to type |
| a deployment id for each bean every time you deploy a jar, you can use the |
| <a href="deploy.html#usage.-D">-D option</a> of the Deploy Tool. This will throw caution |
| to the wind, and automatically assign the bean's ejb-name as the value of the bean's |
| OpenEJB deployment id. This leaves up to you to guarantee that bean's ejb-name will be |
| unique across all beans and jars in the container system. In other words, be very careful |
| with the -D option! |
| </p> |
| </section> |
| |
| <section title="How is it used?" ref-id="usage"> |
| |
| <section title="In the container system" ref-id="usage.containersystem"> |
| <p> |
| In the container system, the deployment id is used to undex the bean in a system-wide |
| registry. This registry is refered to on every call made in the container system. Being |
| able to safely hash and cache bean information by id is a must. This stresses the importance |
| of unique ids for every bean deployed in OpenEJB. |
| </p> |
| </section> |
| |
| <section title="In the Local Server" ref-id="usage.local.server"> |
| <p> |
| The <a href="spec.html#intravm.server">Local (IntraVM) Server</a> is an integral part of |
| the container system and the two are, in many ways, inseparable. The Local Server takes |
| care of all bean to bean and client to bean invocations made inside the virtual machine. |
| For this reason, it often refered to as the IntraVM Server. |
| </p> |
| <p> |
| For bean to bean communications, the Local Server must create a JNDI namespace (JNDI ENC) |
| for each bean as defined by the bean's <env-entry>, <ejb-ref>, and <resource-ref> elements |
| of the bean's ejb-jar.xml file. Every bean litterally gets its very own JNDI namespace. |
| When a bean makes a JNDI call, the Local Server intercepts this call and uses the |
| deployment id of the calling bean to retreive that bean's private JNDI namespace from the |
| container system's index. The Local Server then carries out the lookup on that bean's |
| namespace. |
| </p> |
| <p> |
| All non-bean clients share one big global namespace. Since non-bean clients are not |
| deployed and do not have a deployment descriptor like an ejb-jar.xml, the Local Server is |
| unable to taylor a namespace for each non-bean client as it can for bean clients. The Local |
| server cannot identify non-bean clients as they have no deployment id. All JNDI calls made |
| by clients that the Local Server cannot identify go to the public, global namespace. The |
| public, global JNDI namespace contains all beans and resources in the container system. |
| name. |
| </p> |
| |
| <p> |
| Each bean is added to the public, global namespace using it's deployment id as its JNDI |
| lookup. For example, if a bean had a deployment-id of "/my/bean/foo", a non-bean |
| client could lookup that bean as follows. |
| </p> |
| |
| <p> |
| <file name="c:\my\app\MyAppClient.java"> |
| ... |
| Object bean = initialContext.lookup("/my/bean/Foo"); |
| ... |
| </file> |
| </p> |
| |
| <p> |
| If a bean in the container system made the above JNDI call, the Local Server would see |
| the bean's identity (deployment id) hidden in the Thread, go get the bean's private JNDI |
| namespace and finish the lookup on that. Since all names in bean's JNDI namespace are |
| required start with "java:comp/env", the lookup would fail and the bean would receive a |
| javax.naming.NameNotFoundException. |
| </p> |
| <p> |
| In short... |
| </p> |
| <p> |
| For beans: |
| <ul> |
| <li>Each bean has it's own private, personalized JNDI namespace</li> |
| <li>The names in it are the same names it uses in its ejb-jar.xml</li> |
| <li>Beans can only access their private namespace, period</li> |
| </ul> |
| </p> |
| <p> |
| For non-beans (everyone else): |
| <ul> |
| <li>Non-bean clients share the public, global JNDI namespace</li> |
| <li>The names in it are the deployment ids of all the beans</li> |
| <li>Non-bean clients can only access the one global namespace</li> |
| </ul> |
| </p> |
| |
| </section> |
| |
| <section title="In the Remote Server" ref-id="usage.remote.server"> |
| <p> |
| The Remote Server has a public, global namespace just as the Local Server does. The |
| difference being that the Remote Server only serves clients outside the container system |
| and outside the virtual machine. So, all clients from the perspective of the Remote Server |
| are non-bean clients. As a result, the Remote Server only has the one public, global |
| JNDI namespace. Just as in the Local Server, the names in this namespacse consist of the |
| deployment ids of the beans in the container system. |
| </p> |
| |
| <p> |
| Just as before, clients can lookup beans from the Remote Server using the bean's |
| deployment id. For example, if a bean had a deployment-id of "/my/bean/foo", a |
| client could lookup that bean as follows. |
| </p> |
| |
| <p> |
| <file name="c:\my\app\MyAppClient.java"> |
| ... |
| Object bean = initialContext.lookup("/my/bean/Foo"); |
| ... |
| </file> |
| </p> |
| </section> |
| |
| <section title="In the CORBA Adapter" ref-id="usage.corba.adapter"> |
| <p> |
| The CORBA Adapter is separate than the Remote Server. It adapts the OpenEJB |
| Container System and the Local Server into <a href="http://openorb.sf.net">OpenORB</a> |
| as an embedded library. It provides users of <a href="http://openorb.sf.net">OpenORB</a> |
| the ability to lookup and execute beans (EJBs) via the RMI-IIOP protocol. All the |
| EJBHome and EJBObject interfaces of beans in OpenEJB are implemented by OpenORB as CORBA |
| stubs and ties. |
| </p> |
| <p> |
| The beans are exported into OpenORB's naming service by deployment id. So, just as with the |
| Local Server and Remote Server, clients can lookup beans using the bean's deployment id. |
| OpenORB has a JNDI implementation of their naming service, so lookups can be done just as |
| before. |
| </p> |
| <p> |
| <file name="c:\my\app\MyAppClient.java"> |
| ... |
| Object bean = initialContext.lookup("/my/bean/Foo"); |
| ... |
| </file> |
| </p> |
| <p> |
| CORBA clients can also access beans in OpenEJB as CORBA objects. These can be |
| looked up from OpenORB's naming service (CosNaming) as follows. |
| </p> |
| <p> |
| <code name="c:\my\app\MyCorbaAppClient.java"> |
| ... |
| String[] args = ... |
| |
| <comment>// The ORB and Object</comment> |
| org.omg.CORBA.ORB orb = null; |
| org.omg.CORBA.Object bean = null. |
| |
| <comment>// The Naming Service and Object Name</comment> |
| org.omg.CosNaming.NamingContext context = null; |
| org.omg.CosNaming.NameComponent[] name = null; |
| |
| <comment>// Get the ORB</comment> |
| orb = org.omg.CORBA.ORB.init( args, null ); |
| |
| <comment>// Get the Naming Service </comment> |
| org.omg.CORBA.Object ref = null; |
| ref = orb.resolve_initial_references("NameService"); |
| context = org.omg.CosNaming.NamingContextHelper.narrow( ref ); |
| |
| <comment>// Get the Name as a component |
| // Note: the string is the bean's deployment id </comment> |
| name = new org.omg.CosNaming.NameComponent[ 1 ]; |
| name[0] = new org.omg.CosNaming.NameComponent("/my/bean/foo",""); |
| |
| <comment>// Finally, get the bean as a CORBA object |
| // Equvalent to an InitialContext.lookup("/my/bean/foo");</comment> |
| bean = context.resolve( name ); |
| ... |
| </code> |
| </p> |
| |
| </section> |
| </section> |
| |
| <section title="What happens if there is a duplicate deployment ID?" ref-id="duplicates"> |
| <p> |
| The deployment ID uniquely identifies the bean in the |
| OpenEJB container system. Therefore, no two beans can share the same |
| deployment ID. |
| </p> |
| <p> |
| If a bean attempts to use a deployment ID that is already in |
| use by another bean, the second bean and all beans in it's jar |
| will not be loaded. In addition, the system will log a warning |
| like the following one asking you to redeploy the jar and choose |
| an different deployment ID for the bean. |
| </p> |
| <p> |
| <file name="c:\openejb\openejb.log"> |
| WARN : Jar C:\openejb\beans\fooEjbs.jar cannot be loaded. The |
| Deployment ID "/my/bean/foo" is already in use. Please redeploy |
| this jar and assign a different deployment ID to the bean with |
| the ejb-name "FooBean". |
| </file> |
| </p> |
| |
| <p> |
| For example, the acmeEjbs.jar contains a bean with the ejb-name |
| "DaffyDuckBean". The disneyEjbs.jar contains contains a bean with |
| the ejb-name "DonaldDuckBean". |
| </p> |
| |
| <p> |
| We deploy the acmeEjbs.jar and give the "DaffyDuckBean" the |
| deployment ID of "/my/favorite/duck". Sometime afterwards, |
| we deploy the disneyEjbs.jar and assign the "DonaldDuckBean" |
| the deployment ID "/my/favorite/duck", having forgotten that |
| we already gave that unique ID to the "DaffyDuckBean" in the |
| acmeEjbs.jar. |
| </p> |
| |
| <p> |
| When the container system is started, the system will begin |
| loading all the beans one jar at a time. It will first load the |
| acmeEjbs.jar and index each bean by deployment ID. But, when the |
| system reaches the disneyEjbs.jar, it will discover that it cannot |
| index the "DonaldDuckBean" using the deployment ID "/my/favorite/duck" |
| because that index is already taken. |
| </p> |
| |
| <p> |
| The system cannot load the "DonaldDuckBean" and must also ignore |
| the rest of the beans in the disneyEjbs.jar as they may need the |
| "DonaldDuckBean" bean to function properly. The disneyEjbs.jar |
| is skipped and the following warning is logged. |
| </p> |
| |
| <p> |
| <file name="c:\openejb\openejb.log"> |
| WARN : Jar C:\openejb\beans\disneyEjbs.jar cannot be loaded. The |
| Deployment ID "/my/favorite/duck" is already in use. Please redeploy |
| this jar and assign a different deployment ID to the bean with |
| the ejb-name "DonaldDuckBean". |
| </file> |
| </p> |
| </section> |
| |
| |
| </body> |
| </document> |
| |