blob: 38427c362a174f36cbd1392a5b150d7579ef680e [file] [log] [blame]
<!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 &copy; 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>