blob: 0d8be1f676857cdfa2d2f1aa4a9fd3a7cf3e30ff [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../../favicon.ico">
<link rel="icon" type="image/png" href="../../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../../css/cardio.css">
<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="preloader">
<img src="../../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../../docs.html">Documentation</a></li>
<li><a href="../../../community/index.html">Community</a></li>
<li><a href="../../../security/security.html">Security</a></li>
<li><a href="../../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<h1>Application Composer Getting Started</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>ApplicationComposer API is mainly contained in
<code>org.apache.openejb.testing</code> package (historically, today we would have
called the package <code>org.apache.tomee.applicationcomposer</code>).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_dependencies">Dependencies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To start using ApplicationComposer you need to add some dependencies.</p>
</div>
<div class="paragraph">
<p>The minimum required one is <code>openejb-core</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.apache.openejb&lt;/groupId&gt;
&lt;artifactId&gt;openejb-core&lt;/artifactId&gt;
&lt;version&gt;${openejb.version&gt;&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you need JAXRS services you&#8217;ll add (or replace thanks to transitivity
of maven) <code>openejb-cxf-rs</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.apache.openejb&lt;/groupId&gt;
&lt;artifactId&gt;openejb-cxf-rs&lt;/artifactId&gt;
&lt;version&gt;${openejb.version&gt;&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you need JAXWS services you&#8217;ll add (or replace thanks to transitivity
of maven) <code>openejb-cxf</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.apache.openejb&lt;/groupId&gt;
&lt;artifactId&gt;openejb-cxf&lt;/artifactId&gt;
&lt;version&gt;${openejb.version&gt;&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>etc&#8230;&#8203;</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_applicationcomposer_components">ApplicationComposer Components</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="__module">@Module</h3>
<div class="paragraph">
<p>An ApplicationComposer needs at minimum a module (the application you
need to deploy).</p>
</div>
<div class="paragraph">
<p>To do so you have two cases:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>before TomEE 2.x: you can only write method(s) decorated with
<code>@Module</code></p>
</li>
<li>
<p>since TomEE 2.x: you can skip it and use <code>@Classes</code> directly on the
ApplicationComposer class as a shortcut for:</p>
<div class="paragraph">
<p>@Module public WebApp app() \{ return new WebApp(); }</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The expected returned type of these methods are in
<code>org.apache.openejb.jee</code> package:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Application</code>: entry point to create an ear</p>
</li>
<li>
<p><code>WebApp</code>: a web application</p>
</li>
<li>
<p><code>EjbJar</code>: an ejb module</p>
</li>
<li>
<p><code>EnterpriseBean</code> children: a simple EJB</p>
</li>
<li>
<p><code>Persistence</code>: a persistence module with multiple units</p>
</li>
<li>
<p><code>PersistenceUnit</code>: a simple unit (automatically wrapped in a
<code>Persistence</code>)</p>
</li>
<li>
<p><code>Connector</code>: a JCA connector module</p>
</li>
<li>
<p><code>Beans</code>: a CDI module,</p>
</li>
<li>
<p><code>Class[]</code> or <code>Class</code>: a set of classes scanned to discover annotations</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Note that for easiness <code>@Classes</code> was added to be able to describe a
module and some scanned classes. For instance the following snippet will
create a web application with classes C1, C2 as CDI beans and E1 as an
EJB automatically:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Module
@Classes(cdi = true, value = { C1.class, C2.class, E1.class })
public WebApp app() {
return new WebApp();
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="__configuration">@Configuration</h3>
<div class="paragraph">
<p>Often you need to customize a bit the container or at least create some
resources like test databases. To do so you can create a method
returning <code>Properties</code> which will be the container properties.</p>
</div>
<div class="paragraph">
<p>Note: to simplify writing properties you can use <code>PropertiesBuilder</code>
util class which is just a fluent API to write properties.</p>
</div>
<div class="paragraph">
<p>In these properties you can reuse OpenEJB/TomEE property syntax for
resources.</p>
</div>
<div class="paragraph">
<p>Here is a sample:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Configuration
public Properties configuration() {
return new PropertiesBuilder()
.p("db", "new://Resource?type=DataSource")
.p("db.JdbcUrld", "jdbc:hsqldb:mem:test")
.build();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Since TomEE 2.x you can also put properties on ApplicationComposer class
using <code>@ContainerProperties</code> API:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@ContainerProperties({
@ContainerProperties.Property(name = "db", value = "new://Resource?type=DataSource"),
@ContainerProperties.Property(name = "db.JdbcUrl", value = "jdbc:hsqldb:mem:test")
})
public class MyAppComposer() {
// ...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="__component">@Component</h3>
<div class="paragraph">
<p>Sometimes you need to customize a container component. The most common
use case is the security service to mock a little bit authorization if
you don&#8217;t care in your test.</p>
</div>
<div class="paragraph">
<p>To do so just write a method decorated with <code>@Component</code> returning the
instance you desire.</p>
</div>
<div class="paragraph">
<p>Components in TomEE are stored in a container Map and the key needs to
be a <code>Class</code>. This one is deduced from the returned type of the
<code>@Component</code> method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Component
public SecurityService mockSecurity() {
return new MySecurityService();
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_how_to_run_it">How to run it?</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_junit">JUnit</h3>
<div class="paragraph">
<p>If you use JUnit you have mainly 2 solutions to run you "model" using
the ApplicationComposer:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>using <code>ApplicationComposer</code> runner:</p>
<div class="paragraph">
<p>@RunWith(ApplicationComposer.class) public class MyTest \{ // &#8230;&#8203; }</p>
</div>
</li>
<li>
<p>using <code>ApplicationComposerRule</code> rule:</p>
<div class="paragraph">
<p>public class MyTest \{ <code>@Rule</code> // or <code>@ClassRule</code> if you want the
container/application lifecycle be bound to the class and not test
methods public final ApplicationComposerRule rule = new
ApplicationComposerRule(this); }</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>Tip: since TomEE 2.x ApplicationComposerRule is decomposed in 2 rules if
you need: <code>ContainerRule</code> and <code>DeployApplication</code>. Using JUnit
<code>RuleChain</code> you can chain them to get the samebehavior as
<code>ApplicationComposerRule</code> or better deploy multiple ApplicationComposer
models and controlling their deployment ordering (to mock a remote
service for instance).</p>
</div>
<div class="paragraph">
<p>Finally just write <code>@Test</code> method using test class injections as if the
test class was a managed bean!</p>
</div>
</div>
<div class="sect2">
<h3 id="_testng">TestNG</h3>
<div class="paragraph">
<p>TestNG integration is quite simple today and mainly
<code>ApplicationComposerListener</code> class you can configure as a listener to
get ApplicationComposer features.</p>
</div>
<div class="paragraph">
<p>Finally just write TestNG <code>@Test</code> method using test class injections as
if the test class was a managed bean!</p>
</div>
</div>
<div class="sect2">
<h3 id="_standalone">Standalone</h3>
<div class="paragraph">
<p>Since TomEE 2.x you can also use <code>ApplicationComposers</code> to directly run
you ApplicationComposer model as a standalone application:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class MyApp {
public static void main(String[] args) {
ApplicationComposers.run(MyApp.class, args);
}
// @Module, @Configuration etc...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Tip: if <code>MyApp</code> has <code>@PostConstruct</code> methods they will be respected and
if <code>MyApp</code> has a constructor taking an array of String it will be
instantiated getting the second parameter as argument (ie you can
propagate your main parameter to your model to modify your application
depending it!)</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_junit_sample">JUnit Sample</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Classes(cdi = true, value = { MyService.class, MyOtherService.class })
@ContainerProperties(@ContainerProperties.Property(name = "myDb", value = "new://Resource?type=DataSource"))
@RunWith(ApplicationComposer.class)
public class MyTest {
@Resource(name = "myDb")
private DataSource ds;
@Inject
private MyService service;
@Test
public void myTest() {
// do test using injections
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_going_further">Going further</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you want to learn more about ApplicationComposer see
<a href="advanced.html">Advanced</a> page.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<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>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../../js/jquery-1.11.1.min.js"></script>
<script src="../../../js/owl.carousel.min.js"></script>
<script src="../../../js/bootstrap.min.js"></script>
<script src="../../../js/wow.min.js"></script>
<script src="../../../js/typewriter.js"></script>
<script src="../../../js/jquery.onepagenav.js"></script>
<script src="../../../js/tree.jquery.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/main.js"></script>
</body>
</html>