You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by bu...@apache.org on 2011/07/10 07:37:10 UTC
svn commit: r792466 [15/19] - /websites/staging/openejb/trunk/content/
Added: websites/staging/openejb/trunk/content/simple-stateless-example.cwiki
==============================================================================
--- websites/staging/openejb/trunk/content/simple-stateless-example.cwiki (added)
+++ websites/staging/openejb/trunk/content/simple-stateless-example.cwiki Sun Jul 10 05:37:04 2011
@@ -0,0 +1,118 @@
+h1. Overview
+{span:style=float: right; margin-left: 20px;}
+{html}
+
+<object width="400" height="250"><param name="movie" value="http://www.youtube.com/v/aLx2jta96xU?fs=1&hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/aLx2jta96xU?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="250"></embed></object>
+
+{html}
+{span}
+{div}
+
+
+This example shows how to create a Stateless session EJB using annotations. As stated in the "JSR 220: Enterprise JavaBeansTM,Version 3.0 - EJB Core Contracts and Requirements",
+
+{panel}
+"Stateless session beans are session beans whose instances have no conversational state. This means that all bean instances are equivalent when they are not involved in servicing a client-invoked method. The term 'stateless' signifies that an instance has no state for a specific client."
+{panel}
+
+What this means is quite simply that stateless beans are *shared*. They do in fact have state as you can assign values to the variables, etc. in the bean instance. The only catch is there are a *pool* of identical instances and you are not guaranteed to get the exact same instance on every call. For each call, you get whatever instance happens to be available. This is identical to checking out a book from the library or renting a movie from the video store. You are essentially checking out or renting a new bean instance on each method call.
+
+With EJB 3.0, it's now possible to write stateless session bean without specifying a deployment descriptor; you basically have to write just a remote or local business interface, which is a plain-old-java-interface, annotated with the @Remote or @Local annotation the stateless session bean implementation, a plain-old-java-object which implements the remote or the local business interface and is annotated with the @Stateless annotation
+
+_This example is the "simple-stateless" example located in the [openejb-examples.zip|OPENEJB:Download] available on the download page._
+
+{div}
+{div:style=clear:both;}{div}
+
+h1. The Code
+
+In this example we develop a simple EJB 3 Stateless session EJB. Every stateless session bean implementation must be annotated using the annotation *@Stateless* or marked that way in the ejb-jar.xml file.
+
+Our Stateless bean has 2 business interfaces: CalculatorRemote, a remote business interface, and CalculatorLocal, a local business interface. A minimum of one business interface is required.
+
+h2. Bean
+
+{snippet:id=code|url=openejb3/examples/simple-stateless/src/main/java/org/superbiz/calculator/CalculatorImpl.java|lang=java}
+
+In EJB 3.0 session beans do not need to implement the javax.ejb.SessionBean interface. You can simply annotate it as @Stateless if you want it to be a stateless session bean.
+
+Users of EJB 2.x may notice the bean actually implements the business interfaces! In the prior version of EJB implementing the remote interface (which derives from javax.ejb.EJBObject) in your bean was just not allowed. Now there is no javax.ejb.EJBObject requirement, so implementing the business interfaces is standard practice for EJB 3.0.
+
+h2. Local business interface
+
+{snippet:id=code|url=openejb3/examples/simple-stateless/src/main/java/org/superbiz/calculator/CalculatorLocal.java|lang=java}
+
+Local interfaces in EJB are *pass-by-reference* interfaces. Meaning that *normal java semantics* are used for passing arguments, return values and exceptions. A business local interface can be any plain java interface. There are no restrictions on the method arguments, return types, or throws clauses.
+
+Unless specified otherwise, every interface your bean implements (and it's parent class implements and so on) is considered to be a local business interface. You can use the *@Local* annotation to explicitly state that an interface is a local interface, but this is not required.
+
+You'll notice that in EJB 3.0 the Local Business Interface of a stateless session bean does not need to extend from javax.ejb.EJBLocalObject and does not need a javax.ejb.EJBLocalHome interface as they did in EJB 2.x and prior. Per the vocabulary of the EJB spec, interfaces that implement javax.ejb.EJBLocalObject or javax.ejb.EJBLocalHome are considered Component Interfaces and the plain java interface above is considered a Business Interface.
+
+h2. Remote business interface
+
+{snippet:id=code|url=openejb3/examples/simple-stateless/src/main/java/org/superbiz/calculator/CalculatorRemote.java|lang=java}
+
+Remote interfaces are *pass-by-value* interfaces. Meaning that all method parameters, return values, and exceptions are *serialized* on every call. The result is that you get a copy of the original object and not the original object. The advantage is of course that Remote interfaces can be used to invoke an EJB across a network in a client-server fashion. There are no restrictions on the Remote interface itself, but there are on the data passed in and out of the remote interface. The *values* passed into a method or returned from a method of a Remote interface *must be serializable*. It is fine for the method signature to be, for example, "public Object myMethod(Object myParam)" as long as the *value* passed in and returned implements *java.io.Serializable*.
+
+As stated above, the Remote Business Interface of a bean can be any plain old interface. It does not need to extend javax.ejb.EJBObject, it does not need a javax.ejb.EJBHome, the methods do not need to throw javax.rmi.RemoteException, and the bean class *can* implement it!
+
+At minimum the interface must be annotated with *@Remote* either in the interface itself or in the bean class, or the interface must be declared via <business-remote> in the ejb-jar.xml.
+
+h1. Writing a unit test for the example
+
+Writing an unit test for the stateless session EJb is quite simple. We need just to write a setup method to create and initialize the InitialContext, and then write our test methods
+
+h2. setUp
+
+{snippet:id=setup|url=openejb3/examples/simple-stateless/src/test/java/org/superbiz/calculator/CalculatorTest.java|lang=java}
+
+h2. Test the local business interface
+
+{snippet:id=local|url=openejb3/examples/simple-stateless/src/test/java/org/superbiz/calculator/CalculatorTest.java|lang=java}
+
+h2. Test the remote business interface
+
+{snippet:id=remote|url=openejb3/examples/simple-stateless/src/test/java/org/superbiz/calculator/CalculatorTest.java|lang=java}
+
+{info:title=JNDI Names}
+Note that JNDI names for Java SE clients are not standardized by the EJB spec. This is unfortunate and something being addressed in EJB 3.1. The default schema that OpenEJB uses is ejbName + interfaceType (i.e. Local, Remote, LocalHome, RemoteHome), so in our example "CalculatorImpl" + "Local" and "CalculatorImpl" + "Remote". You can in fact change this default to be absolutely [anything you want|JNDI Names] including interface class name, ejb class name, and more.
+{info}
+
+
+h1. Running
+
+Running the example is fairly simple. In the "simple-stateless" directory of the [examples zip|OPENEJB:Download], just run:
+
+$ mvn clean install
+
+Which should create output like the following.
+
+{noformat}
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running org.superbiz.calculator.CalculatorTest
+Apache OpenEJB 3.0 build: 20080408-04:13
+http://openejb.apache.org/
+INFO - openejb.home = /Users/dblevins/work/openejb-3.0/examples/simple-stateless
+INFO - openejb.base = /Users/dblevins/work/openejb-3.0/examples/simple-stateless
+INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
+INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
+INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory, type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
+INFO - Found EjbModule in classpath: /Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+INFO - Configuring app: /Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
+INFO - Auto-creating a container for bean CalculatorImpl: Container(type=STATELESS, id=Default Stateless Container)
+INFO - Loaded Module: /Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+INFO - Assembling app: /Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+INFO - Jndi(name=CalculatorImplLocal) --> Ejb(deployment-id=CalculatorImpl)
+INFO - Jndi(name=CalculatorImplRemote) --> Ejb(deployment-id=CalculatorImpl)
+INFO - Created Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl, container=Default Stateless Container)
+INFO - Deployed Application(path=/Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes)
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.845 sec
+
+Results :
+
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
+{noformat}
+
Added: websites/staging/openejb/trunk/content/simple-stateless-example.html
==============================================================================
--- websites/staging/openejb/trunk/content/simple-stateless-example.html (added)
+++ websites/staging/openejb/trunk/content/simple-stateless-example.html Sun Jul 10 05:37:04 2011
@@ -0,0 +1,310 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+ <title>Simple Stateless Example</title>
+ <link rel="stylesheet" type="text/css" media="screen" href="http://incubator.apache.org/lucy/css/lucy.css">
+ </head>
+
+ <body>
+
+ <div id="lucy-rigid_wrapper">
+
+ <div id="lucy-top" class="container_16 lucy-white_box_3d">
+
+ <div id="lucy-logo_box" class="grid_8">
+ <a href="/OpenEJB/"><img src="http://openejb.apache.org/images/logo_openejb.gif" alt="Apache OpenEJBâ¢"></a>
+ </div> <!-- lucy-logo_box -->
+
+ <div #id="lucy-top_nav_box" class="grid_8">
+ <div id="lucy-top_nav_bar" class="container_8">
+ <ul>
+ <li><a href="http://www.apache.org/" title="Apache Software Foundation">Apache Software Foundation</a></li>
+ <li><a href="http://www.apache.org/licenses/" title="License">License</a></li>
+ <li><a href="http://www.apache.org/foundation/sponsorship.html" title="Sponsorship">Sponsorship</a></li>
+ <li><a href="http://www.apache.org/foundation/thanks.html" title="Thanks">Thanks</a></li>
+ <li><a href="http://www.apache.org/security/ " title="Security">Security</a></li>
+ </ul>
+ </div> <!-- lucy-top_nav_bar -->
+ <p><a href="http://www.apache.org/">Apache</a> » <a href="/">Incubator</a></p>
+ <form name="lucy-top_search_box" id="lucy-top_search_box" action="http://www.google.com/search" method="get">
+ <input value="*.apache.org" name="sitesearch" type="hidden"/>
+ <input type="text" name="q" id="query" style="width:85%">
+ <input type="submit" id="submit" value="Search">
+ </form>
+ </div> <!-- lucy-top_nav_box -->
+
+ <div class="clear"></div>
+
+ </div> <!-- lucy-top -->
+
+ <div id="lucy-main_content" class="container_16 lucy-white_box_3d">
+
+ <div class="grid_4" id="lucy-left_nav_box">
+ <h6>About</h6>
+ <ul>
+ <li><a href="/lucy/">Welcome</a></li>
+ <li><a href="/lucy/faq.html">FAQ</a></li>
+ <li><a href="/lucy/people.html">People</a></li>
+ </ul>
+ <h6>Resources</h6>
+ <ul>
+ <li><a href="/lucy/download.html">Download</a></li>
+ <li><a href="/lucy/mailing_lists.html">Mailing Lists</a></li>
+ <li><a href="/lucy/docs/perl/">Documentation</a></li>
+ <li><a href="http://wiki.apache.org/lucy/">Wiki</a></li>
+ <li><a href="https://issues.apache.org/jira/browse/LUCY">Issue Tracker</a></li>
+ <li><a href="/lucy/version_control.html">Version Control</a></li>
+ </ul>
+ <h6>Related Projects</h6>
+ <ul>
+ <li><a href="http://lucene.apache.org/java/">Lucene</a></li>
+ <li><a href="http://lucene.apache.org/solr/">Solr</a></li>
+ <li><a href="http://incubator.apache.org/lucene.net/">Lucene.NET</a></li>
+ <li><a href="http://lucene.apache.org/pylucene/">PyLucene</a></li>
+ <li><a href="http://lucene.apache.org/openrelevance/">Open Relevance</a></li>
+ </ul>
+ </div> <!-- lucy-left_nav_box -->
+
+ <div id="lucy-main_content_box" class="grid_9">
+ <p><a name="SimpleStatelessExample-Overview"></a></p>
+
+<h1>Overview</h1>
+
+<p>{span:style=float: right; margin-left: 20px;}
+{html}</p>
+
+<p><object width="400" height="250"><param name="movie"
+value="http://www.youtube.com/v/aLx2jta96xU?fs=1&hl=en_US"></param><param
+name="allowFullScreen" value="true"></param><param name="allowscriptaccess"
+value="always"></param><embed
+src="http://www.youtube.com/v/aLx2jta96xU?fs=1&hl=en_US"
+type="application/x-shockwave-flash" allowscriptaccess="always"
+allowfullscreen="true" width="400" height="250"></embed></object></p>
+
+<p>{html}
+{span}
+{div}</p>
+
+<p>This example shows how to create a Stateless session EJB using annotations.
+ As stated in the "JSR 220: Enterprise JavaBeansTM,Version 3.0 - EJB Core
+Contracts and Requirements",</p>
+
+<p>{panel}
+"Stateless session beans are session beans whose instances have no
+conversational state. This means that all bean instances are equivalent
+when they are not involved in servicing a client-invoked method. The term
+'stateless' signifies that an instance has no state for a specific client."
+{panel}</p>
+
+<p>What this means is quite simply that stateless beans are <em>shared</em>. They do
+in fact have state as you can assign values to the variables, etc. in the
+bean instance. The only catch is there are a <em>pool</em> of identical instances
+and you are not guaranteed to get the exact same instance on every call.
+For each call, you get whatever instance happens to be available. This is
+identical to checking out a book from the library or renting a movie from
+the video store. You are essentially checking out or renting a new bean
+instance on each method call.</p>
+
+<p>With EJB 3.0, it's now possible to write stateless session bean without
+specifying a deployment descriptor; you basically have to write just a
+remote or local business interface, which is a plain-old-java-interface,
+annotated with the @Remote or @Local annotation the stateless session bean
+implementation, a plain-old-java-object which implements the remote or the
+local business interface and is annotated with the @Stateless annotation</p>
+
+<p><em>This example is the "simple-stateless" example located in the <a href="openejb:download.html">openejb-examples.zip</a>
+ available on the download page.</em></p>
+
+<p>{div}
+{div:style=clear:both;}{div}</p>
+
+<p><a name="SimpleStatelessExample-TheCode"></a></p>
+
+<h1>The Code</h1>
+
+<p>In this example we develop a simple EJB 3 Stateless session EJB. Every
+stateless session bean implementation must be annotated using the
+annotation <em>@Stateless</em> or marked that way in the ejb-jar.xml file.</p>
+
+<p>Our Stateless bean has 2 business interfaces: CalculatorRemote, a remote
+business interface, and CalculatorLocal, a local business interface. A
+minimum of one business interface is required.</p>
+
+<p><a name="SimpleStatelessExample-Bean"></a></p>
+
+<h2>Bean</h2>
+
+<p>{snippet:id=code|url=openejb3/examples/simple-stateless/src/main/java/org/superbiz/calculator/CalculatorImpl.java|lang=java}</p>
+
+<p>In EJB 3.0 session beans do not need to implement the javax.ejb.SessionBean
+interface. You can simply annotate it as @Stateless if you want it to be a
+stateless session bean.</p>
+
+<p>Users of EJB 2.x may notice the bean actually implements the business
+interfaces! In the prior version of EJB implementing the remote interface
+(which derives from javax.ejb.EJBObject) in your bean was just not allowed.
+Now there is no javax.ejb.EJBObject requirement, so implementing the
+business interfaces is standard practice for EJB 3.0.</p>
+
+<p><a name="SimpleStatelessExample-Localbusinessinterface"></a></p>
+
+<h2>Local business interface</h2>
+
+<p>{snippet:id=code|url=openejb3/examples/simple-stateless/src/main/java/org/superbiz/calculator/CalculatorLocal.java|lang=java}</p>
+
+<p>Local interfaces in EJB are <em>pass-by-reference</em> interfaces. Meaning that
+<em>normal java semantics</em> are used for passing arguments, return values and
+exceptions. A business local interface can be any plain java interface.
+There are no restrictions on the method arguments, return types, or throws
+clauses. </p>
+
+<p>Unless specified otherwise, every interface your bean implements (and it's
+parent class implements and so on) is considered to be a local business
+interface. You can use the <em>@Local</em> annotation to explicitly state that an
+interface is a local interface, but this is not required.</p>
+
+<p>You'll notice that in EJB 3.0 the Local Business Interface of a stateless
+session bean does not need to extend from javax.ejb.EJBLocalObject and does
+not need a javax.ejb.EJBLocalHome interface as they did in EJB 2.x and
+prior. Per the vocabulary of the EJB spec, interfaces that implement
+javax.ejb.EJBLocalObject or javax.ejb.EJBLocalHome are considered Component
+Interfaces and the plain java interface above is considered a Business
+Interface.</p>
+
+<p><a name="SimpleStatelessExample-Remotebusinessinterface"></a></p>
+
+<h2>Remote business interface</h2>
+
+<p>{snippet:id=code|url=openejb3/examples/simple-stateless/src/main/java/org/superbiz/calculator/CalculatorRemote.java|lang=java}</p>
+
+<p>Remote interfaces are <em>pass-by-value</em> interfaces. Meaning that all method
+parameters, return values, and exceptions are <em>serialized</em> on every call.
+The result is that you get a copy of the original object and not the
+original object. The advantage is of course that Remote interfaces can be
+used to invoke an EJB across a network in a client-server fashion. There
+are no restrictions on the Remote interface itself, but there are on the
+data passed in and out of the remote interface. The <em>values</em> passed into a
+method or returned from a method of a Remote interface <em>must be
+serializable</em>. It is fine for the method signature to be, for example,
+"public Object myMethod(Object myParam)" as long as the <em>value</em> passed in
+and returned implements <em>java.io.Serializable</em>.</p>
+
+<p>As stated above, the Remote Business Interface of a bean can be any plain
+old interface. It does not need to extend javax.ejb.EJBObject, it does not
+need a javax.ejb.EJBHome, the methods do not need to throw
+javax.rmi.RemoteException, and the bean class <em>can</em> implement it!</p>
+
+<p>At minimum the interface must be annotated with <em>@Remote</em> either in the
+interface itself or in the bean class, or the interface must be declared
+via <business-remote> in the ejb-jar.xml.</p>
+
+<p><a name="SimpleStatelessExample-Writingaunittestfortheexample"></a></p>
+
+<h1>Writing a unit test for the example</h1>
+
+<p>Writing an unit test for the stateless session EJb is quite simple. We need
+just to write a setup method to create and initialize the InitialContext,
+and then write our test methods</p>
+
+<p><a name="SimpleStatelessExample-setUp"></a></p>
+
+<h2>setUp</h2>
+
+<p>{snippet:id=setup|url=openejb3/examples/simple-stateless/src/test/java/org/superbiz/calculator/CalculatorTest.java|lang=java}</p>
+
+<p><a name="SimpleStatelessExample-Testthelocalbusinessinterface"></a></p>
+
+<h2>Test the local business interface</h2>
+
+<p>{snippet:id=local|url=openejb3/examples/simple-stateless/src/test/java/org/superbiz/calculator/CalculatorTest.java|lang=java}</p>
+
+<p><a name="SimpleStatelessExample-Testtheremotebusinessinterface"></a></p>
+
+<h2>Test the remote business interface</h2>
+
+<p>{snippet:id=remote|url=openejb3/examples/simple-stateless/src/test/java/org/superbiz/calculator/CalculatorTest.java|lang=java}</p>
+
+<p>{info:title=JNDI Names}
+Note that JNDI names for Java SE clients are not standardized by the EJB
+spec. This is unfortunate and something being addressed in EJB 3.1. The
+default schema that OpenEJB uses is ejbName + interfaceType (i.e. Local,
+Remote, LocalHome, RemoteHome), so in our example "CalculatorImpl" +
+"Local" and "CalculatorImpl" + "Remote". You can in fact change this
+default to be absolutely <a href="jndi-names.html">anything you want</a>
+ including interface class name, ejb class name, and more.
+{info}</p>
+
+<p><a name="SimpleStatelessExample-Running"></a></p>
+
+<h1>Running</h1>
+
+<p>Running the example is fairly simple. In the "simple-stateless" directory
+of the <a href="openejb:download.html">examples zip</a>
+, just run:</p>
+
+<p>$ mvn clean install</p>
+
+<p>Which should create output like the following.</p>
+
+<pre><code>-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running org.superbiz.calculator.CalculatorTest
+Apache OpenEJB 3.0 build: 20080408-04:13
+http://openejb.apache.org/
+INFO - openejb.home =
+</code></pre>
+
+<p>/Users/dblevins/work/openejb-3.0/examples/simple-stateless
+ INFO - openejb.base =
+/Users/dblevins/work/openejb-3.0/examples/simple-stateless
+ INFO - Configuring Service(id=Default Security Service,
+type=SecurityService, provider-id=Default Security Service)
+ INFO - Configuring Service(id=Default Transaction Manager,
+type=TransactionManager, provider-id=Default Transaction Manager)
+ INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
+type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
+ INFO - Found EjbModule in classpath:
+/Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+ INFO - Configuring app:
+/Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+ INFO - Configuring Service(id=Default Stateless Container, type=Container,
+provider-id=Default Stateless Container)
+ INFO - Auto-creating a container for bean CalculatorImpl:
+Container(type=STATELESS, id=Default Stateless Container)
+ INFO - Loaded Module:
+/Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+ INFO - Assembling app:
+/Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes
+ INFO - Jndi(name=CalculatorImplLocal) --> Ejb(deployment-id=CalculatorImpl)
+ INFO - Jndi(name=CalculatorImplRemote) -->
+Ejb(deployment-id=CalculatorImpl)
+ INFO - Created Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl,
+container=Default Stateless Container)
+ INFO - Deployed
+Application(path=/Users/dblevins/work/openejb-3.0/examples/simple-stateless/target/classes)
+ Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.845 sec</p>
+
+<pre><code>Results :
+
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
+</code></pre>
+
+ </div> <!-- lucy-main_content_box -->
+ <div class="clear"></div>
+
+ </div> <!-- lucy-main_content -->
+
+ <div id="lucy-copyright" class="container_16">
+ <p>Copyright © 2010-2011 The Apache Software Foundation, Licensed under the
+ <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
+ <br/>
+
+ </p>
+ </div> <!-- lucy-copyright -->
+
+ </div> <!-- lucy-rigid_wrapper -->
+
+ </body>
+</html>
Modified: websites/staging/openejb/trunk/content/singleton-beans.cwiki
==============================================================================
--- websites/staging/openejb/trunk/content/singleton-beans.cwiki (original)
+++ websites/staging/openejb/trunk/content/singleton-beans.cwiki Sun Jul 10 05:37:04 2011
@@ -1 +1,135 @@
-{include:OPENEJBx30:Singleton Beans}
\ No newline at end of file
+h1. Singleton Overview
+For the first time in years EJB has a new bean type, the *@Singleton*. In my opinion, the javax.ejb.Singleton will replace a lot of what people are using @Stateless for today.
+
+The Singleton is essentially what you get if you take a Stateless bean and adjust the pool size to be exactly 1 resulting in there being exactly one instance of the Singleton bean in the application which can be invoked concurrently by multiple threads, like a servlet. It can do everything a Stateless can do such as support local and remote business interfaces, web services, security, transactions, and more. Additionally, the Singleton can have its @PostConstruct method called with the application starts up and its @PreDestroy method called when the application shuts down. This allows it to serve as an application lifecycle listener which is something only Servlets could do before. It has an *@Startup* annotation which is similar in concept to the servlet <load-on-startup>, but unlike servlets it doesn't take a number as an argument. Instead, you can use an *@DependsOn* annotation to say which other Singletons you need and the container will ensure they start before you
.
+
+See the [Singleton Example] for sample bean code and client.
+
+h2. Concurrency
+
+Singletons support two modes of concurrent access, Container-Managed Concurrency (the default) and Bean-Managed Concurrency.
+
+h3. Bean-Managed Concurrency
+
+With Bean-Managed Concurrency, annotated as *@ConcurrencyManagement(BEAN)*, the container sends all invocations into the bean and lets the Singleton bean instance decide how and when to synchronize access, if at all. Here the 'synchronization' keyword is allowed as well as the full javax.util.concurrent set of libraries.
+
+h3. Container-Managed Concurrency
+
+With Container-Managed Concurrency, annotated as *@ConcurrencyManagement(CONTAINER)*, the container will enforce concurrency for you via locking method access to the bean. Two modes, called locks exist and can be assigned to both the bean class and methods of the bean class.
+
+h4. Lock type
+
+The first and the default is a "write" lock, annotated as *@Lock(WRITE)*. Essentially, with a write lock the caller holds an exclusive lock on the bean for the duration of the method call and all other threads for that or any other method must wait.
+
+The second option is a "read" lock, annotated as *@Lock(READ)*. The read lock allows full concurrent access to the methods (assuming no write locks are held). The default mode of "write" essentially makes your bean a single-threaded bean, which is very slow. The more conservative @Lock(WRITE) was chosen as the default as this is how all the other bean types work (only a single thread may access a bean instance at any given time). Those that are aware of how to handle concurrent access can easily put @Lock(READ) on their bean class, thus changing the default, and then @Lock(WRITE) on specific methods if needed.
+
+The locking modes of Container-Managed Concurrency map directly to the *[java.util.concurrent.ReadWriteLock|http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html]* API which looks like this:
+
+{code:title=java.util.concurrent.ReadWriteLock}
+public interface ReadWriteLock {
+ /**
+ * Returns the lock used for reading.
+ *
+ * @return the lock used for reading.
+ */
+ Lock readLock();
+
+ /**
+ * Returns the lock used for writing.
+ *
+ * @return the lock used for writing.
+ */
+ Lock writeLock();
+}
+{code}
+
+Literally 100% of the Singleton locking we're talking about is taken from this interface and its javadoc is a great source of information. It's safe to imagine that under the covers the Singleton Container has an instance of ReadWriteLock which it uses to enforce the locking for all the Singleton bean's methods. Essentially:
+
+ - @Lock(READ) == theSingletonReadWriteLock.readLock().lock()
+ - @Lock(WRITE) == theSingletonReadWriteLock.writeLock().lock()
+
+The EJB container may use something other than ReadWriteLock but the semantics of a ReadWriteLock must be followed. Internally, we use an instance of [java.util.concurrent.ReentrantReadWriteLock|http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html] which supports correct memory synchronization, some reentrancy, lock downgrading, and [more|http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html].
+
+h4. Acquiring the Lock
+
+The *@AccessTimetout* annotation can configure how long a thread will wait to acquire the read or write lock. This annotation can be used on the bean class or individual methods. The annotation maps directly to the [java.util.concurrent.locks.Lock|http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Lock.html] interface.
+
+{code:title=java.util.concurrent.locks.Lock}
+public interface Lock {
+
+ /**
+ * Blocks (potentially) forever
+ *
+ * @AccessTimout with a value of -1
+ */
+ void lock();
+
+ /**
+ * Non-blocking
+ *
+ * @AccessTimout with a value of 0
+ */
+ boolean tryLock();
+
+ /**
+ * Blocks (potentially) up to a limit
+ *
+ * @AccessTimout(30, TimeUnit.SECONDS)
+ */
+ boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+
+}
+{code}
+
+In the event it is not possible to acquire the lock a *javax.ejb.ConcurrentAccessException* or *javax.ejb.ConcurrentAccessTimeoutException* will be thrown.
+
+h4. Default Timeout
+
+The default value of *@AccessTimeout* annotation is vendor specific. In OpenEJB it defaults to the value of the *AccessTimeout* property which can be configured in many different scopes. Here is the order of preference:
+
+ # bean-level in openejb-jar.xml/<openejb-jar>/<ejb-deployment>/<properties>
+ # jar-level in openejb-jar.xml/<openejb-jar>/<properties>
+ # container-level in openejb.xml/<openejb>/<Container>
+ # boot-level via InitialContext(Properties) or EJBContainer.createEjbContainer(Map<Object,Object>)
+ # system-level in System.getProperties()
+
+The value of the property can be phrased in plain english such as "1 hour and 23 minutes and 17 seconds" see [Configuring Durations] for details.
+
+h2. Startup and Startup Ordering
+
+Singletons have an *@Startup* annotation which can be applied to the bean class. When used, the Container will instantiate the Singleton instance _eagerly_ when the application starts up, otherwise the Container will instantiate the Singleton instance _lazily_ when the bean is first accessed.
+
+If one Singleton refers to another Singleton in the @PostConstruct or @PreDestroy method, there must be some measure taken to ensure the other Singleton exists and is started. This sort of ordering is achieved with the *@DependsOn* annotation which can be used to list the names of Singleton beans that must be started before the Singleton bean using the annotation.
+
+{code}
+@DependsOn({"SingletonB", "SingletonC"})
+@Singleton
+public class SingletonA {
+
+}
+{code}
+
+Circular references are not supported. If BeanA uses @DependsOn to point to BeanB and BeanB also uses @DependsOn to point at BeanA, the result is a deployment exception. Be aware that circular references can happen in less trivial ways such as A referring to B which refers to C which refers to D which refers back to A. We will detect and print all circular dependencies (called circuits) at deploy time.
+
+Note that @DependsOn is only required (and should only be used) if a Singleton *uses* another Singleton in its @PostConstruct method or @PreDestroy method. Simply having a reference to another Singleton and using it in other business methods does not require an @DependsOn declaration. The @DependsOn allows the Container to calculate the correct startup order and shutdown order so that it can guarantee the Singletons you need are available in your @PostConstruct or @PreDestroy methods. All Singletons will automatically be available to your business methods regardless if @DependsOn is used. Because of the greater chance of creating circular dependencies, it is better not to use the @DependsOn annotation "just in case" and should only be used when truly needed.
+
+h1. XML and Annotation Overriding
+
+Singletons can be declared in the ejb-jar.xml as follows:
+
+{code:xml|title=META-INF/ejb-jar.xml}
+<ejb-jar>
+ <enterprise-beans>
+ <session>
+ <ejb-name>MySingletonBean</ejb-name>
+ <ejb-class>org.superbiz.MySingletonBean</ejb-class>
+ <session-type>Singleton</session-type>
+ <load-on-startup/>
+ <depends-on>
+ <ejb-name>SingletonFoo</ejb-name>
+ <ejb-name>SingletonBar</ejb-name>
+ </depends-on>
+ </session>
+ </enterprise-beans>
+</ejb-jar>
+{code}
Modified: websites/staging/openejb/trunk/content/singleton-beans.html
==============================================================================
--- websites/staging/openejb/trunk/content/singleton-beans.html (original)
+++ websites/staging/openejb/trunk/content/singleton-beans.html Sun Jul 10 05:37:04 2011
@@ -67,7 +67,243 @@
</div> <!-- lucy-left_nav_box -->
<div id="lucy-main_content_box" class="grid_9">
- <p>{include:OPENEJBx30:Singleton Beans}</p>
+ <p><a name="SingletonBeans-SingletonOverview"></a></p>
+
+<h1>Singleton Overview</h1>
+
+<p>For the first time in years EJB has a new bean type, the <em>@Singleton</em>. In
+my opinion, the javax.ejb.Singleton will replace a lot of what people are
+using @Stateless for today. </p>
+
+<p>The Singleton is essentially what you get if you take a Stateless bean and
+adjust the pool size to be exactly 1 resulting in there being exactly one
+instance of the Singleton bean in the application which can be invoked
+concurrently by multiple threads, like a servlet. It can do everything a
+Stateless can do such as support local and remote business interfaces, web
+services, security, transactions, and more. Additionally, the Singleton
+can have its @PostConstruct method called with the application starts up
+and its @PreDestroy method called when the application shuts down. This
+allows it to serve as an application lifecycle listener which is something
+only Servlets could do before. It has an <em>@Startup</em> annotation which is
+similar in concept to the servlet <load-on-startup>, but unlike servlets it
+doesn't take a number as an argument. Instead, you can use an <em>@DependsOn</em>
+annotation to say which other Singletons you need and the container will
+ensure they start before you.</p>
+
+<p>See the <a href="singleton-example.html">Singleton Example</a>
+ for sample bean code and client.</p>
+
+<p><a name="SingletonBeans-Concurrency"></a></p>
+
+<h2>Concurrency</h2>
+
+<p>Singletons support two modes of concurrent access, Container-Managed
+Concurrency (the default) and Bean-Managed Concurrency.</p>
+
+<p><a name="SingletonBeans-Bean-ManagedConcurrency"></a></p>
+
+<h3>Bean-Managed Concurrency</h3>
+
+<p>With Bean-Managed Concurrency, annotated as <em>@ConcurrencyManagement(BEAN)</em>,
+the container sends all invocations into the bean and lets the Singleton
+bean instance decide how and when to synchronize access, if at all. Here
+the 'synchronization' keyword is allowed as well as the full
+javax.util.concurrent set of libraries. </p>
+
+<p><a name="SingletonBeans-Container-ManagedConcurrency"></a></p>
+
+<h3>Container-Managed Concurrency</h3>
+
+<p>With Container-Managed Concurrency, annotated as
+<em>@ConcurrencyManagement(CONTAINER)</em>, the container will enforce concurrency
+for you via locking method access to the bean. Two modes, called locks
+exist and can be assigned to both the bean class and methods of the bean
+class.</p>
+
+<p><a name="SingletonBeans-Locktype"></a></p>
+
+<h4>Lock type</h4>
+
+<p>The first and the default is a "write" lock, annotated as <em>@Lock(WRITE)</em>.
+Essentially, with a write lock the caller holds an exclusive lock on the
+bean for the duration of the method call and all other threads for that or
+any other method must wait. </p>
+
+<p>The second option is a "read" lock, annotated as <em>@Lock(READ)</em>. The read
+lock allows full concurrent access to the methods (assuming no write locks
+are held). The default mode of "write" essentially makes your bean a
+single-threaded bean, which is very slow. The more conservative
+@Lock(WRITE) was chosen as the default as this is how all the other bean
+types work (only a single thread may access a bean instance at any given
+time). Those that are aware of how to handle concurrent access can easily
+put @Lock(READ) on their bean class, thus changing the default, and then
+@Lock(WRITE) on specific methods if needed. </p>
+
+<p>The locking modes of Container-Managed Concurrency map directly to the *<a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html">java.util.concurrent.ReadWriteLock</a>
+* API which looks like this:</p>
+
+<p><DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>java.util.concurrent.ReadWriteLock</B></DIV><DIV class="codeContent panelContent">
+ public interface ReadWriteLock {
+ /**
+ * Returns the lock used for reading.
+ *
+ * @return the lock used for reading.
+ */
+ Lock readLock();</p>
+
+<pre><code> /**
+ * Returns the lock used for writing.
+ *
+ * @return the lock used for writing.
+ */
+ Lock writeLock();
+}
+</code></pre>
+
+<p>Literally 100% of the Singleton locking we're talking about is taken from
+this interface and its javadoc is a great source of information. It's safe
+to imagine that under the covers the Singleton Container has an instance of
+ReadWriteLock which it uses to enforce the locking for all the Singleton
+bean's methods. Essentially:</p>
+
+<ul>
+<li>@Lock(READ) == theSingletonReadWriteLock.readLock().lock()</li>
+<li>@Lock(WRITE) == theSingletonReadWriteLock.writeLock().lock()</li>
+</ul>
+
+<p>The EJB container may use something other than ReadWriteLock but the
+semantics of a ReadWriteLock must be followed. Internally, we use an
+instance of <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html">java.util.concurrent.ReentrantReadWriteLock</a>
+ which supports correct memory synchronization, some reentrancy, lock
+downgrading, and [more|http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html]
+.</p>
+
+<p><a name="SingletonBeans-AcquiringtheLock"></a></p>
+
+<h4>Acquiring the Lock</h4>
+
+<p>The <em>@AccessTimetout</em> annotation can configure how long a thread will wait
+to acquire the read or write lock. This annotation can be used on the bean
+class or individual methods. The annotation maps directly to the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Lock.html">java.util.concurrent.locks.Lock</a>
+ interface.</p>
+
+<p><DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>java.util.concurrent.locks.Lock</B></DIV><DIV class="codeContent panelContent">
+ public interface Lock {</p>
+
+<pre><code> /**
+ * Blocks (potentially) forever
+ *
+ * @AccessTimout with a value of -1
+ */
+ void lock();
+
+ /**
+ * Non-blocking
+ *
+ * @AccessTimout with a value of 0
+ */
+ boolean tryLock();
+
+ /**
+ * Blocks (potentially) up to a limit
+ *
+ * @AccessTimout(30, TimeUnit.SECONDS)
+ */
+ boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+
+}
+</code></pre>
+
+<p>In the event it is not possible to acquire the lock a
+<em>javax.ejb.ConcurrentAccessException</em> or
+<em>javax.ejb.ConcurrentAccessTimeoutException</em> will be thrown.</p>
+
+<p><a name="SingletonBeans-DefaultTimeout"></a></p>
+
+<h4>Default Timeout</h4>
+
+<p>The default value of <em>@AccessTimeout</em> annotation is vendor specific. In
+OpenEJB it defaults to the value of the <em>AccessTimeout</em> property which can
+be configured in many different scopes. Here is the order of preference:</p>
+
+<ol>
+<li>bean-level in
+openejb-jar.xml/<openejb-jar>/<ejb-deployment>/<properties></li>
+<li>jar-level in openejb-jar.xml/<openejb-jar>/<properties></li>
+<li>container-level in openejb.xml/<openejb>/<Container></li>
+<li>boot-level via InitialContext(Properties) or
+EJBContainer.createEjbContainer(Map<Object,Object>)</li>
+<li>system-level in System.getProperties()</li>
+</ol>
+
+<p>The value of the property can be phrased in plain english such as "1 hour
+and 23 minutes and 17 seconds" see <a href="configuring-durations.html">Configuring Durations</a>
+ for details.</p>
+
+<p><a name="SingletonBeans-StartupandStartupOrdering"></a></p>
+
+<h2>Startup and Startup Ordering</h2>
+
+<p>Singletons have an <em>@Startup</em> annotation which can be applied to the bean
+class. When used, the Container will instantiate the Singleton instance
+<em>eagerly</em> when the application starts up, otherwise the Container will
+instantiate the Singleton instance <em>lazily</em> when the bean is first
+accessed.</p>
+
+<p>If one Singleton refers to another Singleton in the @PostConstruct or
+@PreDestroy method, there must be some measure taken to ensure the other
+Singleton exists and is started. This sort of ordering is achieved with
+the <em>@DependsOn</em> annotation which can be used to list the names of
+Singleton beans that must be started before the Singleton bean using the
+annotation.</p>
+
+<pre><code>@DependsOn({"SingletonB", "SingletonC"})
+@Singleton
+public class SingletonA {
+
+}
+</code></pre>
+
+<p>Circular references are not supported. If BeanA uses @DependsOn to point
+to BeanB and BeanB also uses @DependsOn to point at BeanA, the result is a
+deployment exception. Be aware that circular references can happen in less
+trivial ways such as A referring to B which refers to C which refers to D
+which refers back to A. We will detect and print all circular dependencies
+(called circuits) at deploy time.</p>
+
+<p>Note that @DependsOn is only required (and should only be used) if a
+Singleton <em>uses</em> another Singleton in its @PostConstruct method or
+@PreDestroy method. Simply having a reference to another Singleton and
+using it in other business methods does not require an @DependsOn
+declaration. The @DependsOn allows the Container to calculate the correct
+startup order and shutdown order so that it can guarantee the Singletons
+you need are available in your @PostConstruct or @PreDestroy methods. All
+Singletons will automatically be available to your business methods
+regardless if @DependsOn is used. Because of the greater chance of
+creating circular dependencies, it is better not to use the @DependsOn
+annotation "just in case" and should only be used when truly needed.</p>
+
+<p><a name="SingletonBeans-XMLandAnnotationOverriding"></a></p>
+
+<h1>XML and Annotation Overriding</h1>
+
+<p>Singletons can be declared in the ejb-jar.xml as follows:</p>
+
+<p>{code:xml|title=META-INF/ejb-jar.xml}
+<ejb-jar>
+ <enterprise-beans>
+ <session>
+ <ejb-name>MySingletonBean</ejb-name>
+ <ejb-class>org.superbiz.MySingletonBean</ejb-class>
+ <session-type>Singleton</session-type>
+ <load-on-startup/>
+ <depends-on>
+ <ejb-name>SingletonFoo</ejb-name>
+ <ejb-name>SingletonBar</ejb-name>
+ </depends-on>
+ </session>
+ </enterprise-beans>
+</ejb-jar></p>
</div> <!-- lucy-main_content_box -->
<div class="clear"></div>
Modified: websites/staging/openejb/trunk/content/singleton-example.cwiki
==============================================================================
--- websites/staging/openejb/trunk/content/singleton-example.cwiki (original)
+++ websites/staging/openejb/trunk/content/singleton-example.cwiki Sun Jul 10 05:37:04 2011
@@ -1 +1,80 @@
-{include:OPENEJBx30:Singleton Example}
\ No newline at end of file
+{tip:title=OpenEJB 3.1 or later required}
+h1. Overview
+
+As the name implies a javax.ejb.Singleton is a session bean with a guarantee that there is at most one instance in the application.
+
+What it gives you that is completely missing in EJB 3.0 and prior versions is the ability to have an EJB that is notified when the application starts and notified when the application stops. So you can do all sorts of things that you previously could only do with a load-on-startup servlet. It also gives you a place to hold data that pertains to the entire application and all users using it, without the need for a static. Additionally, Singleton beans can be invoked by several threads at one time similar to a Servlet.
+
+_See the [Singleton Beans] page for a full description of the javax.ejb.Singleton api._
+
+h1. The Code
+h2. PropertyRegistryBean
+
+Here we see a bean that uses the Bean-Managed Concurrency option as well as the *@Startup* annotation which causes the bean to be instantiated by the container when the application starts. Singleton beans with *@ConcurrencyManagement(BEAN)* are responsible for their own thread-safety. The bean shown is a simple properties "registry" and provides a place where options could be set and retrieved by all beans in the application.
+
+{snippet:url=openejb3/examples/simple-singleton/src/main/java/org/superbiz/registry/PropertyRegistryBean.java|lang=java|id=code}
+
+h2. ComponentRegistryBean
+
+Here we see a bean that uses the Container-Managed Concurrency option, the default. With *@ConcurrencyManagement(CONTAINER)* the container controls whether multi-threaded access should be allowed to the bean (*@Lock(READ)*) or if single-threaded access should be enforced (*@Lock(WRITE)*).
+
+{snippet:url=openejb3/examples/simple-singleton/src/main/java/org/superbiz/registry/ComponentRegistryBean.java|lang=java|id=code}
+
+Unless specified explicitly on the bean class or a method, the default @Lock value is @Lock(WRITE). The code above uses the @Lock(READ) annotation on bean class to change the default so that multi-threaded access is granted by default. We then only need to apply the @Lock(WRITE) annotation to the methods that modify the state of the bean.
+
+Essentially @Lock(READ) allows multithreaded access to the Singleton bean instance *unless* someone is invoking an @Lock(WRITE) method. With @Lock(WRITE), the thread invoking the bean will be guaranteed to have exclusive access to the Singleton bean instance for the duration of its invocation. This combination allows the bean instance to use data types that are not normally thread safe. Great care must still be used, though.
+
+In the example we see ComponentRegistryBean using a java.util.HashMap which is not synchronized. To make this ok we do three things:
+
+ # Encapsulation. We don't expose the HashMap instance directly; including its iterators, key set, value set or entry set.
+ # We use @Lock(WRITE) on the methods that mutate the map such as the put() and remove() methods.
+ # We use @Lock(READ) on the get() and values() methods as they do not change the map state and are guaranteed not to be called at the same as any of the @Lock(WRITE) methods, so we know the state of the HashMap is no being mutated and therefore safe for reading.
+
+The end result is that the threading model for this bean will switch from multi-threaded access to single-threaded access dynamically as needed depending on the which methods are being invoked. This gives Singletons a bit of an advantage over Servlets for processing multi-threaded requests.
+
+_See the [Singleton Beans] page for more advanced details on Container-Managed Concurrency._
+
+h1. Test Case
+
+{snippet:url=openejb3/examples/simple-singleton/src/test/java/org/superbiz/registry/ComponentRegistryBeanTest.java|lang=java|id=code}
+
+h1. Running
+
+Running the example is fairly simple. In the "simple-singleton" directory run:
+
+$ mvn clean install
+
+Which should create output like the following.
+
+{noformat}
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running org.superbiz.registry.ComponentRegistryBeanTest
+Apache OpenEJB 3.1-SNAPSHOT build: 20080820-09:53
+http://openejb.apache.org/
+INFO - openejb.home = /Users/dblevins/work/openejb3/examples/simple-singleton
+INFO - openejb.base = /Users/dblevins/work/openejb3/examples/simple-singleton
+INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
+INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
+INFO - Found EjbModule in classpath: /Users/dblevins/work/openejb3/examples/simple-singleton/target/classes
+INFO - Beginning load: /Users/dblevins/work/openejb3/examples/simple-singleton/target/classes
+INFO - Configuring enterprise application: classpath.ear
+INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container)
+INFO - Auto-creating a container for bean ComponentRegistryBean: Container(type=SINGLETON, id=Default Singleton Container)
+INFO - Enterprise application "classpath.ear" loaded.
+INFO - Assembling app: classpath.ear
+INFO - Jndi(name=ComponentRegistryBeanLocal) --> Ejb(deployment-id=ComponentRegistryBean)
+INFO - Jndi(name=PropertyRegistryBeanLocal) --> Ejb(deployment-id=PropertyRegistryBean)
+INFO - Created Ejb(deployment-id=ComponentRegistryBean, ejb-name=ComponentRegistryBean, container=Default Singleton Container)
+INFO - Created Ejb(deployment-id=PropertyRegistryBean, ejb-name=PropertyRegistryBean, container=Default Singleton Container)
+INFO - Deployed Application(path=classpath.ear)
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.879 sec
+Running org.superbiz.registry.PropertiesRegistryBeanTest
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 sec
+
+Results :
+
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
+{noformat}
+
Modified: websites/staging/openejb/trunk/content/singleton-example.html
==============================================================================
--- websites/staging/openejb/trunk/content/singleton-example.html (original)
+++ websites/staging/openejb/trunk/content/singleton-example.html Sun Jul 10 05:37:04 2011
@@ -67,7 +67,149 @@
</div> <!-- lucy-left_nav_box -->
<div id="lucy-main_content_box" class="grid_9">
- <p>{include:OPENEJBx30:Singleton Example}</p>
+ <p>{tip:title=OpenEJB 3.1 or later required}
+<a name="SingletonExample-Overview"></a></p>
+
+<h1>Overview</h1>
+
+<p>As the name implies a javax.ejb.Singleton is a session bean with a
+guarantee that there is at most one instance in the application.</p>
+
+<p>What it gives you that is completely missing in EJB 3.0 and prior versions
+is the ability to have an EJB that is notified when the application starts
+and notified when the application stops. So you can do all sorts of things
+that you previously could only do with a load-on-startup servlet. It also
+gives you a place to hold data that pertains to the entire application and
+all users using it, without the need for a static. Additionally, Singleton
+beans can be invoked by several threads at one time similar to a Servlet.</p>
+
+<p><em>See the <a href="singleton-beans.html">Singleton Beans</a>
+ page for a full description of the javax.ejb.Singleton api.</em></p>
+
+<p><a name="SingletonExample-TheCode"></a></p>
+
+<h1>The Code</h1>
+
+<p><a name="SingletonExample-PropertyRegistryBean"></a></p>
+
+<h2>PropertyRegistryBean</h2>
+
+<p>Here we see a bean that uses the Bean-Managed Concurrency option as well as
+the <em>@Startup</em> annotation which causes the bean to be instantiated by the
+container when the application starts. Singleton beans with
+<em>@ConcurrencyManagement(BEAN)</em> are responsible for their own thread-safety.
+ The bean shown is a simple properties "registry" and provides a place
+where options could be set and retrieved by all beans in the application.</p>
+
+<p>{snippet:url=openejb3/examples/simple-singleton/src/main/java/org/superbiz/registry/PropertyRegistryBean.java|lang=java|id=code}</p>
+
+<p><a name="SingletonExample-ComponentRegistryBean"></a></p>
+
+<h2>ComponentRegistryBean</h2>
+
+<p>Here we see a bean that uses the Container-Managed Concurrency option, the
+default. With <em>@ConcurrencyManagement(CONTAINER)</em> the container controls
+whether multi-threaded access should be allowed to the bean (<em>@Lock(READ)</em>)
+or if single-threaded access should be enforced (<em>@Lock(WRITE)</em>).</p>
+
+<p>{snippet:url=openejb3/examples/simple-singleton/src/main/java/org/superbiz/registry/ComponentRegistryBean.java|lang=java|id=code}</p>
+
+<p>Unless specified explicitly on the bean class or a method, the default
+@Lock value is @Lock(WRITE). The code above uses the @Lock(READ)
+annotation on bean class to change the default so that multi-threaded
+access is granted by default. We then only need to apply the @Lock(WRITE)
+annotation to the methods that modify the state of the bean.</p>
+
+<p>Essentially @Lock(READ) allows multithreaded access to the Singleton bean
+instance <em>unless</em> someone is invoking an @Lock(WRITE) method. With
+@Lock(WRITE), the thread invoking the bean will be guaranteed to have
+exclusive access to the Singleton bean instance for the duration of its
+invocation. This combination allows the bean instance to use data types
+that are not normally thread safe. Great care must still be used, though. </p>
+
+<p>In the example we see ComponentRegistryBean using a java.util.HashMap which
+is not synchronized. To make this ok we do three things:</p>
+
+<ol>
+<li>Encapsulation. We don't expose the HashMap instance directly; including
+its iterators, key set, value set or entry set.</li>
+<li>We use @Lock(WRITE) on the methods that mutate the map such as the put()
+and remove() methods. </li>
+<li>We use @Lock(READ) on the get() and values() methods as they do not
+change the map state and are guaranteed not to be called at the same as any
+of the @Lock(WRITE) methods, so we know the state of the HashMap is no
+being mutated and therefore safe for reading.</li>
+</ol>
+
+<p>The end result is that the threading model for this bean will switch from
+multi-threaded access to single-threaded access dynamically as needed
+depending on the which methods are being invoked. This gives Singletons a
+bit of an advantage over Servlets for processing multi-threaded requests.</p>
+
+<p><em>See the <a href="singleton-beans.html">Singleton Beans</a>
+ page for more advanced details on Container-Managed Concurrency.</em></p>
+
+<p><a name="SingletonExample-TestCase"></a></p>
+
+<h1>Test Case</h1>
+
+<p>{snippet:url=openejb3/examples/simple-singleton/src/test/java/org/superbiz/registry/ComponentRegistryBeanTest.java|lang=java|id=code}</p>
+
+<p><a name="SingletonExample-Running"></a></p>
+
+<h1>Running</h1>
+
+<p>Running the example is fairly simple. In the "simple-singleton" directory
+run:</p>
+
+<p>$ mvn clean install</p>
+
+<p>Which should create output like the following.</p>
+
+<pre><code>-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running org.superbiz.registry.ComponentRegistryBeanTest
+Apache OpenEJB 3.1-SNAPSHOT build: 20080820-09:53
+http://openejb.apache.org/
+INFO - openejb.home =
+</code></pre>
+
+<p>/Users/dblevins/work/openejb3/examples/simple-singleton
+ INFO - openejb.base =
+/Users/dblevins/work/openejb3/examples/simple-singleton
+ INFO - Configuring Service(id=Default Security Service,
+type=SecurityService, provider-id=Default Security Service)
+ INFO - Configuring Service(id=Default Transaction Manager,
+type=TransactionManager, provider-id=Default Transaction Manager)
+ INFO - Found EjbModule in classpath:
+/Users/dblevins/work/openejb3/examples/simple-singleton/target/classes
+ INFO - Beginning load:
+/Users/dblevins/work/openejb3/examples/simple-singleton/target/classes
+ INFO - Configuring enterprise application: classpath.ear
+ INFO - Configuring Service(id=Default Singleton Container, type=Container,
+provider-id=Default Singleton Container)
+ INFO - Auto-creating a container for bean ComponentRegistryBean:
+Container(type=SINGLETON, id=Default Singleton Container)
+ INFO - Enterprise application "classpath.ear" loaded.
+ INFO - Assembling app: classpath.ear
+ INFO - Jndi(name=ComponentRegistryBeanLocal) -->
+Ejb(deployment-id=ComponentRegistryBean)
+ INFO - Jndi(name=PropertyRegistryBeanLocal) -->
+Ejb(deployment-id=PropertyRegistryBean)
+ INFO - Created Ejb(deployment-id=ComponentRegistryBean,
+ejb-name=ComponentRegistryBean, container=Default Singleton Container)
+ INFO - Created Ejb(deployment-id=PropertyRegistryBean,
+ejb-name=PropertyRegistryBean, container=Default Singleton Container)
+ INFO - Deployed Application(path=classpath.ear)
+ Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.879 sec
+ Running org.superbiz.registry.PropertiesRegistryBeanTest
+ Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 sec</p>
+
+<pre><code>Results :
+
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
+</code></pre>
</div> <!-- lucy-main_content_box -->
<div class="clear"></div>
Modified: websites/staging/openejb/trunk/content/space-index.cwiki
==============================================================================
--- websites/staging/openejb/trunk/content/space-index.cwiki (original)
+++ websites/staging/openejb/trunk/content/space-index.cwiki Sun Jul 10 05:37:04 2011
@@ -1,3 +1,3 @@
+{index}
-{index}
\ No newline at end of file
Added: websites/staging/openejb/trunk/content/spring-and-openejb-3.0.cwiki
==============================================================================
--- websites/staging/openejb/trunk/content/spring-and-openejb-3.0.cwiki (added)
+++ websites/staging/openejb/trunk/content/spring-and-openejb-3.0.cwiki Sun Jul 10 05:37:04 2011
@@ -0,0 +1,191 @@
+{note}OpenEJB 3.1 and later users should refer to the [Spring] page.{note}
+h1. Bootstrapping OpenEJB in Spring
+
+If you wish to use OpenEJB inside Spring you can do so pretty easily. Include OpenEJB and its dependencies in your classpath as you would in a plain embedded scenario then add a custom factory like the following:
+
+{code:title=OpenEjbFactoryBean.java}
+public class OpenEjbFactoryBean implements org.springframework.beans.factory.FactoryBean {
+
+ private Properties properties = new Properties();
+
+ public OpenEjbFactoryBean() {
+ properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
+ }
+
+ public Properties getJndiEnvironment() {
+ return properties;
+ }
+
+ public void setJndiEnvironment(Properties properties) {
+ this.properties.putAll(properties);
+ }
+
+ public Object getObject() {
+ try {
+ return new InitialContext(properties);
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Class getObjectType(){
+ return Context.class;
+ }
+
+ boolean isSingleton() {
+ return true;
+ }
+}
+{code}
+
+And include that at the top of your spring xml file as follows:
+
+{code:xml|title=top of spring xml}
+<bean id="OpenEjbContext" class="org.acme.OpenEjbFactoryBean">
+ <property name="jndiEnvironment">
+ <props>
+ <prop key="myDs">new://Resource?type=DataSource</prop>
+ <prop key="myDs.JdbcDriver">com.mysql.jdbc.Driver</prop>
+ <prop key="myDs.JdbcUrl">jdbc:mysql://localhost/midastest?createDatabaseIfNotExist=true</prop>
+ <prop key="myDs.UserName">root</prop>
+ <prop key="myDs.Password"></prop>
+ </props>
+ </property>
+</bean>
+{code}
+
+The value of <props> is meant to be illustrative of the kinds of properties you can pass into OpenEJB. It's possible to create any number of datasources, topics, queues, containers and more this way.
+
+Just as with Unit Testing, OpenEJB will find and automatically deploy all the EJB beans it [finds in the classpath|Application discovery via the classpath]. You can then expose any of these things to other Spring components with custom factory beans.
+
+h1. Injecting OpenEJB-created resources into Spring components
+
+If you want to have any of the Topics, Queues, DataSources, EntityManagers or more that OpenEJB creates injected into components that Spring creates, here's one technique....
+
+Let's say you have a persistence unit called "*OrangeUnit*" declared in a persistence.xml file. One way to get the related *EntityManager* created by OpenEJB is to do as follows. Create an @Stateless bean with an @PersistenceContext ref in it, then use a factory bean to look it up, pull the EntityManager out and return it
+
+{code:title=OrangeUnitBean.java}
+/*
+ * OpenEJB will automatically find this bean. Just put it in the same jar
+ * that your META-INF/persistence.xml file is located in and make sure that
+ * that same jar file also has a META-INF/ejb-jar.xml file. The ejb-jar.xml
+ * need only contain the text "<ejb-jar/>" at minimum.
+ */
+@Stateless
+public class OrangeUnitBean implements OrangeUnitLocal {
+
+ @PersistenceContext(unitName="OrangeUnit")
+ private EntityManager entityManager;
+
+ public EntityManager getEntityManager() {
+ return entityManager;
+ }
+}
+{code}
+
+{code:title=OrangeUnitLocal.java}
+/**
+ * The local interface for the OrangeUnitBean
+ */
+public interface OrangeUnitLocal {
+ public EntityManager getEntityManager();
+}
+{code}
+
+{code:title=OrangeUnitFactoryBean.java}
+/**
+ * This factory bean will lookup the OrangeUnitBean using the javax.naming.Context
+ * that is created via the OpenEjbFactoryBean above. It will simply grab the EntityManager
+ * from that bean and hand it over to Spring. Anyone in Spring-land can then easily get
+ * a reference to the EntityManager by simply referencing this factory bean.
+ */
+public class OrangeUnitFactoryBean implements org.springframework.beans.factory.FactoryBean {
+ private Context context;
+
+ public Context getContext() {
+ return context;
+ }
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
+
+ public Object getObject() {
+ try {
+ ResourceLocal bean = (ResourceLocal) context.lookup("OrangeUnitBeanLocal");
+ return bean.getEntityManager();
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Class getObjectType(){
+ return EntityManager.class;
+ }
+
+ boolean isSingleton() {
+ return true;
+ }
+}
+{code}
+
+The factory bean would then be declared in your spring xml file as follows:
+
+{code:xml|title=in the spring xml}
+<bean id="OrangeUnit" class="org.acme.OrangeUnitFactoryBean">
+ <property name="context" ref="OpenEjbContext">
+</bean>
+{code}
+
+The EntityManager can then easily be consumed by a spring bean.
+
+{code:title=SomePojo.java}
+public class SomePojo {
+
+ private EntityManager entityManager;
+
+ public void setEntityManager(EntityManager entityManager) {
+ this.entityManager = entityManager;
+ }
+
+ ...
+}
+{code}
+{code:xml|title=in the spring xml}
+<bean id="SomePojo" class="org.acme.SomePojo">
+ <property name="entityManager" ref="OrangeUnit">
+</bean>
+{code}
+
+Here's what all three declarations would look like together in your spring xml:
+
+{code:xml|title=spring bean definitions combined}
+<bean id="OpenEjbContext" class="org.acme.OpenEjbFactoryBean">
+ <property name="jndiEnvironment">
+ <props>
+ <prop key="myDs">new://Resource?type=DataSource</prop>
+ <prop key="myDs.JdbcDriver">com.mysql.jdbc.Driver</prop>
+ <prop key="myDs.JdbcUrl">jdbc:mysql://localhost/midastest?createDatabaseIfNotExist=true</prop>
+ <prop key="myDs.UserName">root</prop>
+ <prop key="myDs.Password"></prop>
+ </props>
+ </property>
+</bean>
+
+<bean id="OrangeUnit" class="org.acme.OrangeUnitFactoryBean">
+ <property name="context" ref="OpenEjbContext">
+</bean>
+
+<bean id="SomePojo" class="org.acme.SomePojo">
+ <property name="entityManager" ref="OrangeUnit">
+</bean>
+{code}
+
+{info:title=Some more useful info.}
+Here is a bunch of links suggested by a user. If anybody has time to go through them and write a doc, that would be great. These links explain how to make available spring components to openejb
+http://twasink.net/blog/archives/2007/01/using_spring_wi.html
+http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html
+http://wiki.netbeans.org/MavenSpringEJBsOnGlassfish
+
+{info}
+
Added: websites/staging/openejb/trunk/content/spring-and-openejb-3.0.html
==============================================================================
--- websites/staging/openejb/trunk/content/spring-and-openejb-3.0.html (added)
+++ websites/staging/openejb/trunk/content/spring-and-openejb-3.0.html Sun Jul 10 05:37:04 2011
@@ -0,0 +1,322 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+ <title>Spring and OpenEJB 3.0</title>
+ <link rel="stylesheet" type="text/css" media="screen" href="http://incubator.apache.org/lucy/css/lucy.css">
+ </head>
+
+ <body>
+
+ <div id="lucy-rigid_wrapper">
+
+ <div id="lucy-top" class="container_16 lucy-white_box_3d">
+
+ <div id="lucy-logo_box" class="grid_8">
+ <a href="/OpenEJB/"><img src="http://openejb.apache.org/images/logo_openejb.gif" alt="Apache OpenEJBâ¢"></a>
+ </div> <!-- lucy-logo_box -->
+
+ <div #id="lucy-top_nav_box" class="grid_8">
+ <div id="lucy-top_nav_bar" class="container_8">
+ <ul>
+ <li><a href="http://www.apache.org/" title="Apache Software Foundation">Apache Software Foundation</a></li>
+ <li><a href="http://www.apache.org/licenses/" title="License">License</a></li>
+ <li><a href="http://www.apache.org/foundation/sponsorship.html" title="Sponsorship">Sponsorship</a></li>
+ <li><a href="http://www.apache.org/foundation/thanks.html" title="Thanks">Thanks</a></li>
+ <li><a href="http://www.apache.org/security/ " title="Security">Security</a></li>
+ </ul>
+ </div> <!-- lucy-top_nav_bar -->
+ <p><a href="http://www.apache.org/">Apache</a> » <a href="/">Incubator</a></p>
+ <form name="lucy-top_search_box" id="lucy-top_search_box" action="http://www.google.com/search" method="get">
+ <input value="*.apache.org" name="sitesearch" type="hidden"/>
+ <input type="text" name="q" id="query" style="width:85%">
+ <input type="submit" id="submit" value="Search">
+ </form>
+ </div> <!-- lucy-top_nav_box -->
+
+ <div class="clear"></div>
+
+ </div> <!-- lucy-top -->
+
+ <div id="lucy-main_content" class="container_16 lucy-white_box_3d">
+
+ <div class="grid_4" id="lucy-left_nav_box">
+ <h6>About</h6>
+ <ul>
+ <li><a href="/lucy/">Welcome</a></li>
+ <li><a href="/lucy/faq.html">FAQ</a></li>
+ <li><a href="/lucy/people.html">People</a></li>
+ </ul>
+ <h6>Resources</h6>
+ <ul>
+ <li><a href="/lucy/download.html">Download</a></li>
+ <li><a href="/lucy/mailing_lists.html">Mailing Lists</a></li>
+ <li><a href="/lucy/docs/perl/">Documentation</a></li>
+ <li><a href="http://wiki.apache.org/lucy/">Wiki</a></li>
+ <li><a href="https://issues.apache.org/jira/browse/LUCY">Issue Tracker</a></li>
+ <li><a href="/lucy/version_control.html">Version Control</a></li>
+ </ul>
+ <h6>Related Projects</h6>
+ <ul>
+ <li><a href="http://lucene.apache.org/java/">Lucene</a></li>
+ <li><a href="http://lucene.apache.org/solr/">Solr</a></li>
+ <li><a href="http://incubator.apache.org/lucene.net/">Lucene.NET</a></li>
+ <li><a href="http://lucene.apache.org/pylucene/">PyLucene</a></li>
+ <li><a href="http://lucene.apache.org/openrelevance/">Open Relevance</a></li>
+ </ul>
+ </div> <!-- lucy-left_nav_box -->
+
+ <div id="lucy-main_content_box" class="grid_9">
+ <p>{note}OpenEJB 3.1 and later users should refer to the <a href="spring.html">Spring</a>
+ page.{note}
+<a name="SpringandOpenEJB3.0-BootstrappingOpenEJBinSpring"></a></p>
+
+<h1>Bootstrapping OpenEJB in Spring</h1>
+
+<p>If you wish to use OpenEJB inside Spring you can do so pretty easily.
+Include OpenEJB and its dependencies in your classpath as you would in a
+plain embedded scenario then add a custom factory like the following:</p>
+
+<p><DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>OpenEjbFactoryBean.java</B></DIV><DIV class="codeContent panelContent">
+ public class OpenEjbFactoryBean implements
+org.springframework.beans.factory.FactoryBean {</p>
+
+<pre><code> private Properties properties = new Properties();
+
+ public OpenEjbFactoryBean() {
+ properties.put(Context.INITIAL_CONTEXT_FACTORY,
+</code></pre>
+
+<p>"org.apache.openejb.client.LocalInitialContextFactory");
+ }</p>
+
+<pre><code> public Properties getJndiEnvironment() {
+ return properties;
+ }
+
+ public void setJndiEnvironment(Properties properties) {
+ this.properties.putAll(properties);
+ }
+
+ public Object getObject() {
+ try {
+ return new InitialContext(properties);
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Class getObjectType(){
+ return Context.class;
+ }
+
+ boolean isSingleton() {
+ return true;
+ }
+}
+</code></pre>
+
+<p>And include that at the top of your spring xml file as follows:</p>
+
+<p>{code:xml|title=top of spring xml}
+<bean id="OpenEjbContext" class="org.acme.OpenEjbFactoryBean">
+ <property name="jndiEnvironment">
+ <props>
+ <prop key="myDs">new://Resource?type=DataSource</prop>
+ <prop key="myDs.JdbcDriver">com.mysql.jdbc.Driver</prop>
+ <prop
+key="myDs.JdbcUrl">jdbc:mysql://localhost/midastest?createDatabaseIfNotExist=true</prop>
+ <prop key="myDs.UserName">root</prop>
+ <prop key="myDs.Password"></prop>
+ </props>
+ </property>
+</bean></p>
+
+<pre><code>The value of <props> is meant to be illustrative of the kinds of properties
+</code></pre>
+
+<p>you can pass into OpenEJB. It's possible to create any number of
+datasources, topics, queues, containers and more this way.</p>
+
+<pre><code>Just as with Unit Testing, OpenEJB will find and automatically deploy all
+</code></pre>
+
+<p>the EJB beans it [finds in the classpath|Application discovery via the classpath]
+. You can then expose any of these things to other Spring components with
+custom factory beans.</p>
+
+<pre><code>h1. Injecting OpenEJB-created resources into Spring components
+
+If you want to have any of the Topics, Queues, DataSources, EntityManagers
+</code></pre>
+
+<p>or more that OpenEJB creates injected into components that Spring creates,
+here's one technique....</p>
+
+<pre><code>Let's say you have a persistence unit called "*OrangeUnit*" declared in a
+</code></pre>
+
+<p>persistence.xml file. One way to get the related <em>EntityManager</em> created
+by OpenEJB is to do as follows. Create an @Stateless bean with an
+@PersistenceContext ref in it, then use a factory bean to look it up, pull
+the EntityManager out and return it</p>
+
+<pre><code>{code:title=OrangeUnitBean.java}
+/*
+ * OpenEJB will automatically find this bean. Just put it in the same jar
+ * that your META-INF/persistence.xml file is located in and make sure that
+ * that same jar file also has a META-INF/ejb-jar.xml file. The
+</code></pre>
+
+<p>ejb-jar.xml
+ * need only contain the text "<ejb-jar/>" at minimum.
+ */
+ @Stateless
+ public class OrangeUnitBean implements OrangeUnitLocal {</p>
+
+<pre><code> @PersistenceContext(unitName="OrangeUnit")
+ private EntityManager entityManager;
+
+ public EntityManager getEntityManager() {
+ return entityManager;
+ }
+}
+</code></pre>
+
+<p><DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>OrangeUnitLocal.java</B></DIV><DIV class="codeContent panelContent">
+ /**
+ * The local interface for the OrangeUnitBean
+ */
+ public interface OrangeUnitLocal {
+ public EntityManager getEntityManager();
+ }</p>
+
+<p><DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>OrangeUnitFactoryBean.java</B></DIV><DIV class="codeContent panelContent">
+ /**
+ * This factory bean will lookup the OrangeUnitBean using the
+javax.naming.Context
+ * that is created via the OpenEjbFactoryBean above. It will simply grab
+the EntityManager
+ * from that bean and hand it over to Spring. Anyone in Spring-land can
+then easily get
+ * a reference to the EntityManager by simply referencing this factory
+bean.
+ */
+ public class OrangeUnitFactoryBean implements
+org.springframework.beans.factory.FactoryBean {
+ private Context context;</p>
+
+<pre><code> public Context getContext() {
+ return context;
+ }
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
+
+ public Object getObject() {
+ try {
+ ResourceLocal bean = (ResourceLocal)
+</code></pre>
+
+<p>context.lookup("OrangeUnitBeanLocal");
+ return bean.getEntityManager();
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }</p>
+
+<pre><code> public Class getObjectType(){
+ return EntityManager.class;
+ }
+
+ boolean isSingleton() {
+ return true;
+ }
+}
+</code></pre>
+
+<p>The factory bean would then be declared in your spring xml file as follows:</p>
+
+<p>{code:xml|title=in the spring xml}
+<bean id="OrangeUnit" class="org.acme.OrangeUnitFactoryBean">
+ <property name="context" ref="OpenEjbContext">
+</bean></p>
+
+<pre><code>The EntityManager can then easily be consumed by a spring bean.
+
+{code:title=SomePojo.java}
+public class SomePojo {
+
+ private EntityManager entityManager;
+
+ public void setEntityManager(EntityManager entityManager) {
+ this.entityManager = entityManager;
+ }
+
+ ...
+}
+</code></pre>
+
+<p>{code:xml|title=in the spring xml}
+<bean id="SomePojo" class="org.acme.SomePojo">
+ <property name="entityManager" ref="OrangeUnit">
+</bean></p>
+
+<pre><code>Here's what all three declarations would look like together in your spring
+</code></pre>
+
+<p>xml:</p>
+
+<pre><code>{code:xml|title=spring bean definitions combined}
+<bean id="OpenEjbContext" class="org.acme.OpenEjbFactoryBean">
+ <property name="jndiEnvironment">
+ <props>
+ <prop key="myDs">new://Resource?type=DataSource</prop>
+ <prop key="myDs.JdbcDriver">com.mysql.jdbc.Driver</prop>
+ <prop
+</code></pre>
+
+<p>key="myDs.JdbcUrl">jdbc:mysql://localhost/midastest?createDatabaseIfNotExist=true</prop>
+ <prop key="myDs.UserName">root</prop>
+ <prop key="myDs.Password"></prop>
+ </props>
+ </property>
+ </bean></p>
+
+<pre><code><bean id="OrangeUnit" class="org.acme.OrangeUnitFactoryBean">
+ <property name="context" ref="OpenEjbContext">
+</bean>
+
+<bean id="SomePojo" class="org.acme.SomePojo">
+ <property name="entityManager" ref="OrangeUnit">
+</bean>
+</code></pre>
+
+<p>{info:title=Some more useful info.}
+Here is a bunch of links suggested by a user. If anybody has time to go
+through them and write a doc, that would be great. These links explain how
+to make available spring components to openejb
+http://twasink.net/blog/archives/2007/01/using_spring_wi.html
+http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html
+http://wiki.netbeans.org/MavenSpringEJBsOnGlassfish</p>
+
+<p>{info} </p>
+
+ </div> <!-- lucy-main_content_box -->
+ <div class="clear"></div>
+
+ </div> <!-- lucy-main_content -->
+
+ <div id="lucy-copyright" class="container_16">
+ <p>Copyright © 2010-2011 The Apache Software Foundation, Licensed under the
+ <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
+ <br/>
+
+ </p>
+ </div> <!-- lucy-copyright -->
+
+ </div> <!-- lucy-rigid_wrapper -->
+
+ </body>
+</html>
Added: websites/staging/openejb/trunk/content/spring-ejb-and-jpa.cwiki
==============================================================================
--- websites/staging/openejb/trunk/content/spring-ejb-and-jpa.cwiki (added)
+++ websites/staging/openejb/trunk/content/spring-ejb-and-jpa.cwiki Sun Jul 10 05:37:04 2011
@@ -0,0 +1,108 @@
+{note}OpenEJB 3.1 or later required{note}
+This example shows how to combine Spring, OpenEJB and Hibernate using the integration code provided by OpenEJB. Here, OpenEJB is used as an embeddable EJB container inside of Spring. See the [Spring] page for details.
+
+We use the basic Movie example and expand it to include more objects to demonstrate both Spring beans, EJB Session beans, and JPA persistent objects in one application. The premise of the example is a Cineplex that has a number of Theaters (viewing screens), each playing a number of Movies. The basic object layout is as follows:
+
+|| Object || Type || Description ||
+| [CineplexImpl|http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/CineplexImpl.java] | @Stateless | Shows the use of @Resource to have Spring beans injected. Specifically, the _Theaters_ Spring bean |
+| [Theaters|http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/Theaters.java] | Spring bean | Simple wrapper object injected into _CineplexImpl_ |
+| [Theater|http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/Theater.java] | Spring bean | Shows that EJBs can be injected into Spring beans. Uses both the _Movies_ EJB and the _Movie_ JPA objects |
+| [MoviesImpl|http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/MoviesImpl.java] | @Stateful | Wraps a JPA EntityManager and provides transactional access to the persistent _Movie_ objects |
+| [Movie|http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/Movie.java] | @Entity | Basic JPA bean that is used both by Spring beans and EJBs. The same _Movie_ object as in all the other persistence related examples. |
+| [AvailableMovies|http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/AvailableMovies.java] | Spring bean | Simple object used as a clever way to seed the EntityManager (and really, the database) with persistent _Movie_ objects |
+
+h1. Required jars
+
+To setup the integration you'll need:
+
+# The standard OpenEJB 3.1 libraries
+# The [openejb-spring-3.1.jar|https://repository.apache.org/content/groups/public/org/apache/openejb/openejb-spring/3.1.2/openejb-spring-3.1.2.jar] or later
+# Spring 2.5 or other (any version should work)
+
+In Maven2 this can be done by adding the following dependencies to your pom.xml
+{snippet:id=required|url=openejb3/examples/spring-integration/pom.xml|lang=xml}
+For other environments, you can simply [download an openejb-3.1.zip|OPENEJB:Download] or later and include all the jars under the lib/ directory in your classpath. Then download and add the [openejb-spring-3.1.jar|http://people.apache.org/repo/m2-ibiblio-rsync-repository/org/apache/openejb/openejb-spring/3.1/openejb-spring-3.1.jar] along with your Spring jars.
+
+h1. The Spring xml
+
+Bootstrapping and Configuring OpenEJB is fairly simple.
+{snippet:id=bootstrapping|url=openejb3/examples/spring-integration/src/main/resources/movies.xml|lang=xml}
+As well, you can optionally declare any resources or containers. Anything declarable as a <Resource> or <Container> in the openejb.xml can instead be declared in the Spring xml file as shown here.
+{snippet:id=resources|url=openejb3/examples/spring-integration/src/main/resources/movies.xml|lang=xml}
+And finally our Spring beans.
+{snippet:id=pojos|url=openejb3/examples/spring-integration/src/main/resources/movies.xml|lang=xml}
+{note:title=Don't forget}
+{snippet:id=annotations|url=openejb3/examples/spring-integration/src/main/resources/movies.xml|lang=xml}
+It allows various annotations to be detected in bean classes: Spring's @Required and @Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available), JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's @PersistenceContext and @PersistenceUnit (if available). Alternatively, you may choose to activate the individual BeanPostProcessors for those annotations.
+{note}
+
+h1. The Code
+
+In efforts to keep the example page somewhat short, we'll show just three beans, each demonstrating a particular relationship.
+
+The first is the CineplexImpl EJB which shows EJB \-> Spring.
+{snippet:id=code|url=openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/CineplexImpl.java|lang=java}
+
+The second is the Theater Spring bean which shows Spring \-> EJB.
+{snippet:id=code|url=openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/Theater.java|lang=java}
+
+The last is the AvailableMovies Spring bean which Shows Spring \-> EJB \-> JPA
+{snippet:id=code|url=openejb3/examples/spring-integration/src/main/java/org/superbiz/spring/AvailableMovies.java|lang=java}
+
+h1. The TestCase
+
+The JUnit TestCase uses a ClassPathXmlApplicationContext to load the Spring ApplicationContext. Anything that loads your Spring xml file should work fine. The following code would work a plain java app as well.
+
+{snippet:id=code|url=openejb3/examples/spring-integration/src/test/java/org/superbiz/spring/MoviesTest.java|lang=java}
+
+h1. Running
+
+The source for this example can be downloaded from svn via:
+
+$ svn co [http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/spring-integration]
+
+Then, in the "spring-integration" directory, run:
+
+$ mvn clean install
+
+Which should create output like the following.
+
+{noformat}
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running org.superbiz.spring.MoviesTest
+log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
+log4j:WARN Please initialize the log4j system properly.
+Apache OpenEJB 3.1 build: 20081009-03:31
+http://openejb.apache.org/
+INFO - openejb.home = /Users/dblevins/work/openejb3/examples/spring-integration
+INFO - openejb.base = /Users/dblevins/work/openejb3/examples/spring-integration
+INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory, type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
+INFO - Configuring Service(id=MovieDatabase, type=Resource, provider-id=Default JDBC Database)
+INFO - Configuring Service(id=MovieDatabaseUnmanaged, type=Resource, provider-id=Default JDBC Database)
+INFO - Found EjbModule in classpath: /Users/dblevins/work/openejb3/examples/spring-integration/target/classes
+INFO - Beginning load: /Users/dblevins/work/openejb3/examples/spring-integration/target/classes
+INFO - Configuring enterprise application: classpath.ear
+INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
+INFO - Auto-creating a container for bean CineplexImpl: Container(type=STATELESS, id=Default Stateless Container)
+INFO - Auto-linking resource-ref 'org.superbiz.spring.CineplexImpl/theaters' in bean CineplexImpl to Resource(id=theaters)
+INFO - Configuring Service(id=Default Stateful Container, type=Container, provider-id=Default Stateful Container)
+INFO - Auto-creating a container for bean Movies: Container(type=STATEFUL, id=Default Stateful Container)
+INFO - Configuring PersistenceUnit(name=movie-unit, provider=org.hibernate.ejb.HibernatePersistence)
+INFO - Enterprise application "classpath.ear" loaded.
+INFO - Assembling app: classpath.ear
+INFO - PersistenceUnit(name=movie-unit, provider=org.hibernate.ejb.HibernatePersistence)
+INFO - Jndi(name=CineplexImplLocal) --> Ejb(deployment-id=CineplexImpl)
+INFO - Jndi(name=MoviesLocal) --> Ejb(deployment-id=Movies)
+INFO - Created Ejb(deployment-id=Movies, ejb-name=Movies, container=Default Stateful Container)
+INFO - Created Ejb(deployment-id=CineplexImpl, ejb-name=CineplexImpl, container=Default Stateless Container)
+INFO - Deployed Application(path=classpath.ear)
+INFO - Exported EJB Movies with interface org.superbiz.spring.Movies to Spring bean MoviesLocal
+INFO - Exported EJB CineplexImpl with interface org.superbiz.spring.Cineplex to Spring bean CineplexImplLocal
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.141 sec
+
+Results :
+
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
+{noformat}
\ No newline at end of file