blob: 07144a57864f24688a651702fe6a6291e8d6fd57 [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>Serverless Builder API</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>The <code>Server.Builder</code> API allows you to build an embedded or serverless instance of Tomcat/TomEE inside your JVM, effectively running Tomcat/TomEE as a plain library.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import org.apache.tomee.bootstrap.Server;
public class Main {
public static void main(String[] args) {
final Server server = Server.builder().build();
System.out.println("Listening for requests at " + server.getURI());
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The design of the API might be best described as a functional-builder API (FBA) and effectively allows you to supply functions and method references that actually assist in the server building process. Its through these functions that you can deploy applications, modify configurations and effectively run any code that you need that would help prepare the server instance.</p>
</div>
<div class="paragraph">
<p>A high-level overview of the builder methods available after calling <code>Server.builder()</code> are as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public static class Builder
public Builder httpPort(final int port)
public Builder ajpPort(final int port)
public Builder add(final String name, final byte[] bytes)
public Builder add(final String name, final Supplier&lt;byte[]&gt; content)
public Builder add(final String name, final String content)
public Builder add(final String name, final File content)
public Builder add(final String name, final Archive contents)
public Builder home(final Consumer&lt;File&gt; customization)
public Builder and(final Consumer&lt;Builder&gt; consumer)
public Server build()</code></pre>
</div>
</div>
<div class="paragraph">
<p>To really know how to use the API, we must first understand Tomcat&#8217;s <code>catalina.home</code> and <code>catalina.base</code> concepts and what actually happens when we call <code>Server.builder().build()</code></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_understanding_tomcat_s_home_and_base">Understanding Tomcat&#8217;s home and base</h3>
<div class="paragraph">
<p>It&#8217;s a little known fact that for decades Tomcat has had the ability to run several instances from a single Tomcat zip. Tomcat uses a <code>catalina.home</code> variable to identify the location of the extracted zip where the server libraries can be found and a <code>catalina.base</code> per instance to define the location of that instance&#8217;s configuration files, log files and webapps.</p>
</div>
<div class="paragraph">
<p>In our situation, your JVM classpath is effectively the <code>catalina.home</code> and when we use the <code>Server</code> API we&#8217;re creating a very thin <code>catalina.base</code> that holds the configuration files, log files and webapps for that built Server (Tomcat) instance. If you use the <code>Server</code> API ten times in the same JVM, you will have 10 <code>catalina.base</code> directories. These are considered temporary working locations, however, and will be deleted on JVM exit.</p>
</div>
</div>
<div class="sect2">
<h3 id="_calling_code_server_builder_build_code">Calling <code>Server.builder().build()</code></h3>
<div class="paragraph">
<p>When the <code>build()</code> method of the <code>Server.Builder</code> is called the following actions are taken in this order:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Any functions added via <code>and(final Consumer&lt;Builder&gt; consumer)</code> are executed. This allows a function to be supplied that further modifies the builder just before any building is executed. Several builder modifications can be wrapped into one function that installs them all.</p>
</li>
<li>
<p>A temp directory is created that will serve as <code>catalina.home</code> and <code>catalina.base</code> and default configurations such as <code>server.xml</code>, <code>logging.properties</code>, and <code>tomee.xml</code> are copied in.</p>
</li>
<li>
<p>Any functions added via <code>add(final String destinationPath, final Supplier&lt;byte[]&gt; content)</code> are executed and any supplied bytes, Strings or Files are written to the <code>destinationPath</code> inside the temp directory. This allows the default configurations like <code>server.xml</code> to be overwritten or applications to be written to the <code>webapps/</code> directory.</p>
</li>
<li>
<p>Ports are set by modifying the <code>conf/server.xml</code>. If <code>httpPort</code> was not set, ports will be random.</p>
</li>
<li>
<p>Any functions added via <code>home(final Consumer&lt;File&gt; customization)</code> are executed. The temp directory will be supplied as the value of <code>File</code>.</p>
</li>
<li>
<p>The Tomcat/TomEE instance is started and returned as an instance of <code>Server</code></p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="_seeing_the_result_of_code_server_builder_build_code">Seeing the Result of <code>Server.builder().build()</code></h3>
<div class="paragraph">
<p>It helps greatly to be able to see what was built. We can do that by installing a function or method reference like the one below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import org.apache.tomee.bootstrap.Server;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Server.builder()
.home(Main::list)
.build();
}
private static void list(final File home) {
try {
Files.walk(home.toPath())
.sorted()
.forEach(System.out::println);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When we run that we should see output similar to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/catalina.policy
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/catalina.properties
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/context.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/jaspic-providers.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/jaspic-providers.xsd
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/logging.properties
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/server.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/system.properties
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomcat-users.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomcat-users.xsd
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomee.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/web.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/logs
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/webapps</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above represents what comes out of the box from calling <code>Server.builder().build()</code> with no modifications.</p>
</div>
</div>
<div class="sect1">
<h2 id="_creating_apps_with_code_archive_code">Creating Apps with <code>Archive</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The second class to learn is <code>Archive</code> and is essentially a no-frills app builder. With this approach all your classes are effectively already in the classpath and visible, so ultimately the only classes that need to be included are annotated Servlets, EJBs, CDI Beans, JAX-RS classes, etc.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class Archive
public static Archive archive()
public Archive manifest(final String key, final Object value)
public Archive manifest(final String key, final Class value)
public Archive add(final String name, final byte[] bytes)
public Archive add(final String name, final Supplier&lt;byte[]&gt; content)
public Archive add(final String name, final String content)
public Archive add(final String name, final File content)
public Archive add(final String name, final Archive archive)
public Archive add(final String name, final URL content)
public Archive add(final Class&lt;?&gt; clazz)
public Archive addDir(final File dir)
public Archive addJar(final File file)
public File toJar()
public File toJar(final File file)
public File toDir()
public void toDir(final File dir)</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You can use APIs like ShrinkWrap to build the jars and war files as an alternative to <code>Archive</code>. Anything that can produce a jar file, war file or an exploded (unzipped) war directory structure will work.
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="_creating_a_root_war">Creating a ROOT war</h3>
<div class="paragraph">
<p>In this example we are effectively adding three classes to an <code>Archive</code> which is itself added to a new <code>webapps/ROOT/WEB-INF/classes</code> directory.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import org.apache.tomee.bootstrap.Archive;
import org.apache.tomee.bootstrap.Server;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
public class Main {
public static void main(String[] args) {
final Server server = Server.builder()
.add("webapps/ROOT/WEB-INF/classes", Archive.archive()
.add(Api.class)
.add(Movie.class)
.add(MovieService.class))
.home(Main::list)
.build();
System.out.println("Listening for requests at " + server.getURI());
}
private static void list(final File home) {
try {
Files.walk(home.toPath())
.map(Path::toFile)
.filter(File::isFile)
.map(File::getAbsolutePath)
.map(s -&gt; "..." + s.substring(49))
.sorted()
.forEach(System.out::println);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When this runs we&#8217;ll see out <code>Main.list</code> method which executes just before server start will have printed the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">...temp710654453954858189dir/apache-tomee/conf/catalina.policy
...temp710654453954858189dir/apache-tomee/conf/catalina.properties
...temp710654453954858189dir/apache-tomee/conf/context.xml
...temp710654453954858189dir/apache-tomee/conf/jaspic-providers.xml
...temp710654453954858189dir/apache-tomee/conf/jaspic-providers.xsd
...temp710654453954858189dir/apache-tomee/conf/logging.properties
...temp710654453954858189dir/apache-tomee/conf/server.xml
...temp710654453954858189dir/apache-tomee/conf/system.properties
...temp710654453954858189dir/apache-tomee/conf/tomcat-users.xml
...temp710654453954858189dir/apache-tomee/conf/tomcat-users.xsd
...temp710654453954858189dir/apache-tomee/conf/tomee.xml
...temp710654453954858189dir/apache-tomee/conf/web.xml
...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/Api.class
...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/Movie.class
...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/MovieService.class</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_apis_used">APIs Used</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="../../latest/javadoc/org/apache/tomee/bootstrap/Archive.html">org.apache.tomee.bootstrap.Archive</a></p>
</li>
<li>
<p><a href="../../latest/javadoc/org/apache/tomee/bootstrap/Server.html">org.apache.tomee.bootstrap.Server</a></p>
</li>
</ul>
</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>