| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| |
| <meta charset="UTF-8"> |
| <title>Embedded and Remotable</title> |
| <meta name="description" content="Apache TomEE"> |
| <meta name="author" content="Apache TomEE"> |
| <meta name="google-translate-customization" content="f36a520c08f4c9-0a04e86a9c075ce9-g265f3196f697cf8f-10"> |
| <meta http-equiv="Pragma" content="no-cache"> |
| <meta http-equiv="Expires" content="0"> |
| <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0"> |
| |
| <!-- Le HTML5 shim, for IE6-8 support of HTML elements --> |
| <!--[if lt IE 9]> |
| <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> |
| <![endif]--> |
| |
| <!-- Le styles --> |
| <link href="./resources/css/bootstrap.css" rel="stylesheet"> |
| <link href="./resources/css/prettify.css" rel="stylesheet"> |
| <!--link href="./resources/css/bootstrap-mods.css" rel="stylesheet"--> |
| <link href="./resources/css/main.css" rel="stylesheet"> |
| <link href="./resources/font-awesome-4.6.3/css/font-awesome.min.css" rel="stylesheet"> |
| |
| <script type="text/javascript"> |
| var t = encodeURIComponent(document.title.replace(/^\s+|\s+$/g,"")); |
| var u = encodeURIComponent(""+document.URL); |
| |
| function fbshare () { |
| window.open( |
| "http://www.facebook.com/sharer/sharer.php?u="+u, |
| 'Share on Facebook', |
| 'width=640,height=426'); |
| }; |
| function gpshare () { |
| window.open( |
| "https://plus.google.com/share?url="+u, |
| 'Share on Google+', |
| 'width=584,height=385'); |
| }; |
| function twshare () { |
| window.open( |
| "https://twitter.com/intent/tweet?url="+u+"&text="+t, |
| 'Share on Twitter', |
| 'width=800,height=526'); |
| }; |
| function pinshare () { |
| window.open("//www.pinterest.com/pin/create/button/?url="+u+"&media=http%3A%2F%2Ftomee.apache.org%2Fresources%2Fimages%2Ffeather-logo.png&description="+t, |
| 'Share on Pinterest', |
| 'width=800,height=526'); |
| }; |
| </script> |
| |
| <!-- Le fav and touch icons --> |
| <link rel="shortcut icon" href="./favicon.ico"> |
| <link rel="apple-touch-icon" href="./resources/images/apple-touch-icon.png"> |
| <link rel="apple-touch-icon" sizes="72x72" href="./resources/images/apple-touch-icon-72x72.png"> |
| <link rel="apple-touch-icon" sizes="114x114" href="./resources/images/apple-touch-icon-114x114.png"> |
| |
| <script src="./resources/js/prettify.js" type="text/javascript"></script> |
| <script src="./resources/js/jquery-latest.js"></script> |
| <script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script> |
| <script src="./resources/js/common.js"></script> |
| <script src="./resources/js/prettyprint.js"></script> |
| <!--script src="//assets.pinterest.com/js/pinit.js" type="text/javascript" async></script//--> |
| |
| <script type="text/javascript"> |
| |
| var _gaq = _gaq || []; |
| _gaq.push(['_setAccount', 'UA-2717626-1']); |
| _gaq.push(['_setDomainName', 'apache.org']); |
| _gaq.push(['_trackPageview']); |
| |
| (function() { |
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
| })(); |
| |
| </script> |
| </head> |
| |
| <body> |
| |
| <div class="topbar" data-dropdown="dropdown"> |
| <div class="fill"> |
| <div class="container"> |
| <a class="brand" href="./index.html">Apache TomEE</a> |
| <ul class="nav"> |
| <li class="dropdown"> |
| <a class="dropdown-toggle" data-toggle="dropdown" href="#"> |
| Apache |
| <b class="caret"></b> |
| </a> |
| <ul class="dropdown-menu"> |
| <!-- <li><a href="./misc/whoweare.html">Who we are?</a></li> --> |
| <!-- <li><a href="./misc/heritage.html">Heritage</a></li> --> |
| <li><a href="http://www.apache.org">Apache Home</a></li> |
| <!-- <li><a href="./misc/resources.html">Resources</a></li> --> |
| <li><a href="./misc/contact.html">Contact</a></li> |
| <li><a href="./misc/legal.html">Legal</a></li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li> |
| <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li> |
| <li class="divider"/> |
| <li><a href="http://www.apache.org/security">Security</a></li> |
| </ul> |
| </li> |
| <li><a href="./index.html">Home</a></li> |
| <li><a href="./downloads.html">Downloads</a></li> |
| <li><a href="./documentation.html">Documentation</a></li> |
| <li><a href="./examples-trunk/index.html">Examples</a></li> |
| <li><a href="./support.html">Support</a></li> |
| <li><a href="./contribute.html">Contribute</a></li> |
| <li><a href="./security/index.html">Security</a></li> |
| </ul> |
| |
| <!-- Google CSE Search Box Begins --> |
| <FORM class="pull-right" id="searchbox_010475492895890475512:_t4iqjrgx90" action="http://www.google.com/cse"> |
| <INPUT type="hidden" name="cx" value="010475492895890475512:_t4iqjrgx90"> |
| <INPUT type="hidden" name="cof" value="FORID:0"> |
| <INPUT size="18" width="130" style="width:130px" name="q" type="text" placeholder="Search"> |
| </FORM> |
| <!--<SCRIPT type="text/javascript" src="http://www.google.com/coop/cse/brand?form=searchbox_010475492895890475512:_t4iqjrgx90"></SCRIPT>--> |
| <!-- Google CSE Search Box Ends --> |
| </div> |
| </div> |
| </div> |
| |
| <div class="container"> |
| |
| |
| <div class="page-header"> |
| <small><a href="./index.html">Home</a></small><br> |
| <h1>Embedded and Remotable |
| |
| <div style="float: right; position: relative; bottom: -10px; "> |
| <a onclick="javascript:gpshare()" class="gp-share sprite" title="Share on Google+">share [gp]</a> |
| <a onclick="javascript:fbshare()" class="fb-share sprite" title="Share on Facebook">share [fb]</a> |
| <a onclick="javascript:twshare()" class="tw-share sprite" title="Share on Twitter">share [tw]</a> |
| <a onclick="javascript:pinshare()" class="pin-share sprite" title="Share on Pinterest">share [pin]</a> |
| <a data-toggle="modal" href="#edit" class="edit-page" title="Contribute to this Page">contribute</a> |
| </div> |
| </h1> |
| </div> |
| |
| <p><a name="EmbeddedandRemotable-Overview"></a></p> |
| |
| <h1>Overview</h1> |
| |
| <p>This example shows how to use OpenEJB3's remoting capabilities in an |
| embedded scenario. By remoting we mean that you wish to allow <em>clients in |
| other vms</em> access your ejbs. <em>Note, you do not need to go to this extreme |
| to unit test ejbs with remote interfaces.</em></p> |
| |
| <p>The basic recipe is the same for a standard embedded scenario but with |
| these added ingreditents:</p> |
| |
| <ul> |
| <li><em>openejb.embedded.remotable</em> property</li> |
| <li><em>openejb-ejbd</em> jar</li> |
| </ul> |
| |
| <p>While creating the InitialContext, pass in the openejb.embedded.remotable |
| property with the value of "true". When this is seen by the |
| LocalInitialContextFactory, it will boot up the Server ServiceManager in |
| the VM which will in turn look for ServerServices in the classpath.</p> |
| |
| <p>Provided you have the openejb-ejbd jar in your classpath along with it's |
| dependencies (openejb-server, openejb-client, openejb-core), then those |
| services will be brought online and remote clients will be able to connect |
| into your vm and invoke beans.</p> |
| |
| <p>If you want to add more ServerServices such as the http version of the ejbd |
| protocol you'd simply add the openejb-httpejbd jar to your classpath. A |
| number of ServerServices are available currently:</p> |
| |
| <ul> |
| <li>openejb-ejbd</li> |
| <li>openejb-http</li> |
| <li>openejb-telnet</li> |
| <li>openejb-derbynet</li> |
| <li>openejb-hsql</li> |
| <li>openejb-activemq</li> |
| </ul> |
| |
| <p><em>The source for this example is in the "telephone-stateful" directory |
| located in the <a href="openejb:download.html">openejb-examples.zip</a> |
| available on the <a href="http://tomee.apache.org/downloads.html">download page</a>.</em> |
| <div class="note">} |
| If your goal is simply to unit test beans with remote interfaces, this is |
| <em>not</em> the right example for you. The LocalInitialContextFactory completely |
| supports remote interfaces and all spec required pass-by-value |
| (serialization) semantics without the need for network sockets. This |
| example shows the use of OpenEJB in an embedded environment where |
| connection <em>outside</em> the |
| vm is required.{note}</p> |
| |
| <p><a name="EmbeddedandRemotable-TheCode"></a></p> |
| |
| <h1>The Code</h1> |
| |
| <p>For this example we have a simple Stateful bean called TelephoneBean as |
| defined below. As a simple way of demonstrating the state we have to |
| methods: speak and listen. You call <em>speak</em> and pass in some text, then |
| you call <em>listen</em> to get your answer.</p> |
| |
| <p><a name="EmbeddedandRemotable-bean"></a></p> |
| |
| <h2>bean</h2> |
| |
| <p><div class="snippet">:id=code|url=openejb3/examples/telephone-stateful/src/main/java/org/superbiz/telephone/TelephoneBean.java|lang=java}</p> |
| |
| <p><a name="EmbeddedandRemotable-businessinterface"></a></p> |
| |
| <h2>business interface</h2> |
| |
| <p><div class="snippet">:id=code|url=openejb3/examples/telephone-stateful/src/main/java/org/superbiz/telephone/Telephone.java|lang=java} |
| <div class="tip">:title=EJB3 Notes} |
| The bean class uses the annotation <em>@Remote</em> but does not specify a list of |
| interfaces as is normally required. Per EJB3 rules, if the bean implements |
| exactly <em>one business interface</em> it may use @Remote with no other values |
| and that business interface is then implied to be a remote business |
| interface. The same rule applies to identical usage of @Local.</p> |
| |
| <p>The critical thing to know is that if you add another interface the rules |
| change and require that you specify both interfaces in the @Remote |
| annotation as in @Remote({Telephone.class, SecondInterface.class}).<div class="tip">}</p> |
| |
| <p><a name="EmbeddedandRemotable-Embedding"></a></p> |
| |
| <h1>Embedding</h1> |
| |
| <p>We're going to embed OpenEJB3 into a plain JUnit TestCase as a simple means |
| of demonstrating the remote capabilities. We'll do the embedding in our |
| test setUp method, then will make two test methods: |
| - one for invoking the bean's remote interface via the |
| <em>LocalInitialContextFactory</em> which goes straight against the embedded |
| container system |
| - one for invoking the bean's remote interface via the |
| <em>RemoteInitialContextFactory</em> which connects to a Socket and communicates |
| to the embedded container system over the ejbd protocol.</p> |
| |
| <p><a name="EmbeddedandRemotable-setUp"></a></p> |
| |
| <h2>setUp</h2> |
| |
| <p><div class="snippet">:id=setup|url=openejb3/examples/telephone-stateful/src/test/java/org/superbiz/telephone/TelephoneTest.java|lang=java}</p> |
| |
| <h2>LocalInitialContextFactory: making in-vm calls to a remote business</h2> |
| |
| <p>interface |
| <div class="snippet">:id=localcontext|url=openejb3/examples/telephone-stateful/src/test/java/org/superbiz/telephone/TelephoneTest.java|lang=java}</p> |
| |
| <h2>RemoteInitialContextFactory: making networked calls to a remote</h2> |
| |
| <p>business interface</p> |
| |
| <p>This is the part you would want to do in apps that are running a different |
| VM than the one in which the ejb container is embedded. These "client" VMs |
| need only have the the <em>openejb-client jar</em> in their classpath and connect |
| to OpenEJB via the RemoteInitialContextFactory like any other remote EJB |
| client. |
| <div class="snippet">:id=remotecontext|url=openejb3/examples/telephone-stateful/src/test/java/org/superbiz/telephone/TelephoneTest.java|lang=java}</p> |
| |
| <p><a name="EmbeddedandRemotable-Mavensetup"></a></p> |
| |
| <h1>Maven setup</h1> |
| |
| <p><div class="snippet">:id=desc|url=openejb3/examples/telephone-stateful/pom.xml} |
| <div class="snippet">:id=openejbdep|url=openejb3/examples/telephone-stateful/pom.xml|lang=xml}</p> |
| |
| <p><a name="EmbeddedandRemotable-Running"></a></p> |
| |
| <h1>Running</h1> |
| |
| <p>Running the example is fairly simple. In the "telephone-stateful" |
| 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.telephone.TelephoneTest |
| Apache OpenEJB 3.0 build: 20080408-04:13 |
| http://tomee.apache.org/ |
| INFO - openejb.home = |
| </code></pre> |
| |
| <p>/Users/dblevins/work/openejb-3.0/examples/telephone-stateful |
| INFO - openejb.base = |
| /Users/dblevins/work/openejb-3.0/examples/telephone-stateful |
| 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/telephone-stateful/target/classes |
| INFO - Configuring app: |
| /Users/dblevins/work/openejb-3.0/examples/telephone-stateful/target/classes |
| INFO - Configuring Service(id=Default Stateful Container, type=Container, |
| provider-id=Default Stateful Container) |
| INFO - Auto-creating a container for bean TelephoneBean: |
| Container(type=STATEFUL, id=Default Stateful Container) |
| INFO - Loaded Module: |
| /Users/dblevins/work/openejb-3.0/examples/telephone-stateful/target/classes |
| INFO - Assembling app: |
| /Users/dblevins/work/openejb-3.0/examples/telephone-stateful/target/classes |
| INFO - Jndi(name=TelephoneBeanRemote) --> Ejb(deployment-id=TelephoneBean) |
| INFO - Created Ejb(deployment-id=TelephoneBean, ejb-name=TelephoneBean, |
| container=Default Stateful Container) |
| INFO - Deployed |
| Application(path=/Users/dblevins/work/openejb-3.0/examples/telephone-stateful/target/classes) |
| <em>* Starting Services *</em> |
| NAME IP PORT <br /> |
| ejbd 127.0.0.1 4201 <br /> |
| admin thread 127.0.0.1 4200 <br /> |
| ------- |
| Ready! |
| Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.89 sec</p> |
| |
| <pre><code>Results : |
| |
| Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 |
| </code></pre> |
| |
| |
| |
| |
| <div id="edit" class="modal hide fade in" style="display: none; "> |
| <div class="modal-header"> |
| <a class="close" data-dismiss="modal">x</a> |
| |
| <h3>Thank you for contributing to the documentation!</h3> |
| </div> |
| <div class="modal-body"> |
| <h4>Any help with the documentation is greatly appreciated.</h4> |
| <p>All edits are reviewed before going live, so feel free to do much more than fix typos or links. If you see a page that could benefit from an entire rewrite, we'd be thrilled to review it. Don't be surprised if we like it so much we ask you for help with other pages :)</p> |
| <small>NOTICE: unless indicated otherwise on the pages in question, all editable content available from apache.org is presumed to be licensed under the Apache License (AL) version 2.0 and hence all submissions to apache.org treated as formal Contributions under the license terms.</small> |
| <!--[if gt IE 6]> |
| <h4>Internet Explorer Users</h4> |
| <p>If you are not an Apache committer, click the Yes link and enter a <i>anonymous</i> for the username and leave the password empty</p> |
| <![endif]--> |
| |
| </div> |
| <div class="modal-footer"> |
| Do you have an Apache ID? |
| <a href="javascript:void(location.href='https://cms.apache.org/redirect?uri='+escape(location.href))" class="btn">Yes</a> |
| <a href="javascript:void(location.href='https://anonymous:@cms.apache.org/redirect?uri='+escape(location.href))" class="btn">No</a> |
| </div> |
| </div> |
| <script src="./resources/js/bootstrap-modal.js"></script> |
| |
| <footer> |
| <p>Copyright © 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. |
| Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. |
| All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p> |
| </footer> |
| |
| </div> <!-- /container --> |
| |
| <!-- Javascript |
| ================================================== --> |
| <!-- Placed at the end of the document so the pages load faster --> |
| <script src="./resources/js/bootstrap-dropdown.js"></script> |
| |
| </body> |
| </html> |