You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2020/09/04 01:34:20 UTC

[tomee] branch master updated: Examples and documentation TOMEE-2706 New TomEE Embedded Bootstrap

This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee.git


The following commit(s) were added to refs/heads/master by this push:
     new 142f035  Examples and documentation TOMEE-2706 New TomEE Embedded Bootstrap
142f035 is described below

commit 142f035e454b43192c51db7a66b9395982502d47
Author: David Blevins <da...@gmail.com>
AuthorDate: Thu Sep 3 18:34:01 2020 -0700

    Examples and documentation
    TOMEE-2706 New TomEE Embedded Bootstrap
---
 .../src/main/java/org/superbiz/movie/wp/Api.java   |  24 +++
 .../src/main/java/org/superbiz/movie/wp/Movie.java |  77 ++++++++++
 .../java/org/superbiz/movie/wp/MovieService.java   |  60 ++++++++
 .../org/superbiz/movie/wp/MovieServiceTest.java    |  87 +++++++++++
 examples/serverless-tomee-plume/README.adoc        | 168 +++++++++++++++++++++
 examples/serverless-tomee-plume/pom.xml            |  74 +++++++++
 .../src/main/java/org/superbiz/movie/Api.java      |  24 +++
 .../src/main/java/org/superbiz/movie/Movie.java    |  77 ++++++++++
 .../main/java/org/superbiz/movie/MovieService.java |  60 ++++++++
 .../src/test/java/org/superbiz/movie/Main.java     |  35 +++++
 .../java/org/superbiz/movie/MovieServiceTest.java  |  87 +++++++++++
 examples/serverless-tomee-plus/README.adoc         | 168 +++++++++++++++++++++
 examples/serverless-tomee-plus/pom.xml             |  74 +++++++++
 .../src/main/java/org/superbiz/movie/Api.java      |  24 +++
 .../src/main/java/org/superbiz/movie/Movie.java    |  77 ++++++++++
 .../main/java/org/superbiz/movie/MovieService.java |  60 ++++++++
 .../src/test/java/org/superbiz/movie/Main.java     |  35 +++++
 .../java/org/superbiz/movie/MovieServiceTest.java  |  87 +++++++++++
 examples/serverless-tomee-webprofile/README.adoc   | 168 +++++++++++++++++++++
 examples/serverless-tomee-webprofile/pom.xml       |  74 +++++++++
 .../src/main/java/org/superbiz/movie/wp/Api.java   |  24 +++
 .../src/main/java/org/superbiz/movie/wp/Movie.java |  77 ++++++++++
 .../java/org/superbiz/movie/wp/MovieService.java   |  60 ++++++++
 .../src/test/java/org/superbiz/movie/wp/Main.java  |  33 ++++
 .../org/superbiz/movie/wp/MovieServiceTest.java    |  87 +++++++++++
 25 files changed, 1821 insertions(+)

diff --git a/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Api.java b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Api.java
new file mode 100644
index 0000000..320fddc
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Api.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Movie.java b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Movie.java
new file mode 100644
index 0000000..b5b02df
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+public class Movie {
+
+    private String title;
+    private String director;
+    private String genre;
+    private int id;
+    private int year;
+
+    public Movie() {
+    }
+
+    public Movie(final String title, final String director, final String genre, final int id, final int year) {
+        this.title = title;
+        this.director = director;
+        this.genre = genre;
+        this.id = id;
+        this.year = year;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+
+    public String getDirector() {
+        return director;
+    }
+
+    public void setDirector(final String director) {
+        this.director = director;
+    }
+
+    public String getGenre() {
+        return genre;
+    }
+
+    public void setGenre(final String genre) {
+        this.genre = genre;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(final int id) {
+        this.id = id;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public void setYear(final int year) {
+        this.year = year;
+    }
+}
diff --git a/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/MovieService.java b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
new file mode 100644
index 0000000..d12ef58
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
diff --git a/examples/serverless-tomee-microprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java b/examples/serverless-tomee-microprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java
new file mode 100644
index 0000000..23e1274
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+
+    @Test
+    public void addMovie() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+        final Movie posted = target.path("/api/movies").request()
+                .post(entity(movie, MediaType.APPLICATION_JSON))
+                .readEntity(Movie.class);
+
+        assertEquals("Tom Dey", posted.getDirector());
+        assertEquals("Shanghai Noon", posted.getTitle());
+        assertEquals("Comedy", posted.getGenre());
+        assertEquals(2000, posted.getYear());
+        assertEquals(7, posted.getId());
+    }
+}
diff --git a/examples/serverless-tomee-plume/README.adoc b/examples/serverless-tomee-plume/README.adoc
new file mode 100644
index 0000000..73a2ed4
--- /dev/null
+++ b/examples/serverless-tomee-plume/README.adoc
@@ -0,0 +1,168 @@
+:index-group: Serverless
+:jbake-type: page
+:jbake-status: status=published
+= Serverless TomEE Plume
+
+Apache TomEE can be run as a library inside your JVM with no need for separate processes or a standalone server install.  In this approach we include the right libraries in our project and then bootstrap TomEE using the `Server.Builder` API.
+
+== Include the `tomee-plume` dependency
+
+To make things as easy as possible there is just one dependency that will give you a classpath that is 100% identical to your favorite Apache TomEE distribution.  The following dependency will pull give you an environment identical to an Apache TomEE Plume binary distribution.
+
+[source,xml]
+----
+<dependency>
+  <groupId>org.apache.tomee.bom</groupId>
+  <artifactId>tomee-plume</artifactId>
+  <version>${version.tomee}</version>
+</dependency>
+----
+
+NOTE: The `org.apache.tomee.bom:tomee-plume` is actually generated by analyzing the apache-tomee-plume-x.y.z.zip, so is guaranteed to be 100% identical making it easy to transition from a zip file to a simple maven dependency.
+
+== Write Regular Code
+
+Here we see a simple JAX-RS API for sending/recieving `Movie` objects as JSON.
+
+[source,java]
+----
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
+----
+
+== Bootstrap TomEE with the Server Builder
+
+A this point we have a Maven project with the right dependencies and some application code in our project.  From here we use the `Server.Builder` API to construct a `Server` instance inside our JVM.
+
+Here we see a simple Main class that bootstraps a `Server` instance on port `8080` and blocks:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+import java.util.concurrent.Semaphore;
+
+public class Main {
+    public static void main(String[] args) throws InterruptedException {
+
+        final Server server = Server.builder()
+                .httpPort(8080)
+                .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+                        .add(Api.class)
+                        .add(Movie.class)
+                        .add(MovieService.class))
+                .build();
+
+        System.out.println("Listening for requests at " + server.getURI());
+        new Semaphore(0).acquire();
+    }
+}
+----
+
+The example below bootstraps a `Server` instance on random ports inside a test case and exits when the test case is complete:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+//...
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+}
+----
+
+In the above code we have assembled the classes `Api`, `Movie` and `MovieService` into a virtual archive, then we add that archive into a virtual Tomcat install at the location `webapps/ROOT/WEB-INF/classes`.  When we call `build()` the Tomcat server instance is started in our JVM and will begin serving HTTP requests at the host/port identified by `server.getURI()`
+
+In short, we've bootstrapped a Tomcat server in our JVM that has a very tiny disk footprint; three classes and a handful of default configuration files.
+
+== Running
+
+Were we to run the above Main class or Test Case we'd see output like the following:
+
+[source,bash]
+----
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener deployApplication
+INFO:      org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@2d313c8c
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: REST Application: http://localhost:8080/api        -> org.superbiz.movie.Api@6b2dd3df
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:      Service URI: http://localhost:8080/api/movies -> Pojo org.superbiz.movie.MovieService
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:               GET http://localhost:8080/api/movies ->      List<Movie> getAllMovies()
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:              POST http://localhost:8080/api/movies ->      Movie addMovie(Movie)     
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Deployment of web application directory [/private/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp14966428831095231081dir/apache-tomee/webapps/ROOT] has finished in [1,798] ms
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Starting ProtocolHandler ["http-nio-8080"]
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Server startup in [1877] milliseconds
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Full bootstrap in [3545] milliseconds
+Listening for requests at http://localhost:8080
+----
diff --git a/examples/serverless-tomee-plume/pom.xml b/examples/serverless-tomee-plume/pom.xml
new file mode 100644
index 0000000..b7fd7f9
--- /dev/null
+++ b/examples/serverless-tomee-plume/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.superbiz</groupId>
+  <artifactId>serverless-tomee-plume</artifactId>
+  <version>8.0.5-SNAPSHOT</version>
+
+  <name>TomEE :: Examples :: Serverless Apache TomEE Plume</name>
+  
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <version.tomee>8.0.5-SNAPSHOT</version.tomee>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomee.bom</groupId>
+      <artifactId>tomee-webprofile</artifactId>
+      <version>${version.tomee}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.5.1</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!--
+  This section allows you to configure where to publish libraries for sharing.
+  It is not required and may be deleted.  For more information see:
+  http://maven.apache.org/plugins/maven-deploy-plugin/
+  -->
+  <distributionManagement>
+    <repository>
+      <id>localhost</id>
+      <url>file://${basedir}/target/repo/</url>
+    </repository>
+    <snapshotRepository>
+      <id>localhost</id>
+      <url>file://${basedir}/target/snapshot-repo/</url>
+    </snapshotRepository>
+  </distributionManagement>
+</project>
diff --git a/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Api.java b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Api.java
new file mode 100644
index 0000000..a7c43d3
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Api.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Movie.java b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Movie.java
new file mode 100644
index 0000000..450959b
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie;
+
+public class Movie {
+
+    private String title;
+    private String director;
+    private String genre;
+    private int id;
+    private int year;
+
+    public Movie() {
+    }
+
+    public Movie(final String title, final String director, final String genre, final int id, final int year) {
+        this.title = title;
+        this.director = director;
+        this.genre = genre;
+        this.id = id;
+        this.year = year;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+
+    public String getDirector() {
+        return director;
+    }
+
+    public void setDirector(final String director) {
+        this.director = director;
+    }
+
+    public String getGenre() {
+        return genre;
+    }
+
+    public void setGenre(final String genre) {
+        this.genre = genre;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(final int id) {
+        this.id = id;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public void setYear(final int year) {
+        this.year = year;
+    }
+}
diff --git a/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/MovieService.java b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/MovieService.java
new file mode 100644
index 0000000..b8acbc2
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
diff --git a/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/Main.java b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/Main.java
new file mode 100644
index 0000000..2f077aa
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/Main.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie;
+
+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());
+    }
+
+
+//    public static void main(String[] args) {
+//        Server.builder()
+//                .home(file -> Stream.of(file.listFiles()).forEach(System.out::println))
+//                .build();
+//    }
+//
+}
diff --git a/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/MovieServiceTest.java b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/MovieServiceTest.java
new file mode 100644
index 0000000..08b5a69
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/MovieServiceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+
+    @Test
+    public void addMovie() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+        final Movie posted = target.path("/api/movies").request()
+                .post(entity(movie, MediaType.APPLICATION_JSON))
+                .readEntity(Movie.class);
+
+        assertEquals("Tom Dey", posted.getDirector());
+        assertEquals("Shanghai Noon", posted.getTitle());
+        assertEquals("Comedy", posted.getGenre());
+        assertEquals(2000, posted.getYear());
+        assertEquals(7, posted.getId());
+    }
+}
diff --git a/examples/serverless-tomee-plus/README.adoc b/examples/serverless-tomee-plus/README.adoc
new file mode 100644
index 0000000..5852df5
--- /dev/null
+++ b/examples/serverless-tomee-plus/README.adoc
@@ -0,0 +1,168 @@
+:index-group: Serverless
+:jbake-type: page
+:jbake-status: status=published
+= Serverless TomEE Plus
+
+Apache TomEE can be run as a library inside your JVM with no need for separate processes or a standalone server install.  In this approach we include the right libraries in our project and then bootstrap TomEE using the `Server.Builder` API.
+
+== Include the `tomee-plus` dependency
+
+To make things as easy as possible there is just one dependency that will give you a classpath that is 100% identical to your favorite Apache TomEE distribution.  The following dependency will pull give you an environment identical to an Apache TomEE Plus binary distribution.
+
+[source,xml]
+----
+<dependency>
+  <groupId>org.apache.tomee.bom</groupId>
+  <artifactId>tomee-plus</artifactId>
+  <version>${version.tomee}</version>
+</dependency>
+----
+
+NOTE: The `org.apache.tomee.bom:tomee-plus` is actually generated by analyzing the apache-tomee-plus-x.y.z.zip, so is guaranteed to be 100% identical making it easy to transition from a zip file to a simple maven dependency.
+
+== Write Regular Code
+
+Here we see a simple JAX-RS API for sending/recieving `Movie` objects as JSON.
+
+[source,java]
+----
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
+----
+
+== Bootstrap TomEE with the Server Builder
+
+A this point we have a Maven project with the right dependencies and some application code in our project.  From here we use the `Server.Builder` API to construct a `Server` instance inside our JVM.
+
+Here we see a simple Main class that bootstraps a `Server` instance on port `8080` and blocks:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+import java.util.concurrent.Semaphore;
+
+public class Main {
+    public static void main(String[] args) throws InterruptedException {
+
+        final Server server = Server.builder()
+                .httpPort(8080)
+                .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+                        .add(Api.class)
+                        .add(Movie.class)
+                        .add(MovieService.class))
+                .build();
+
+        System.out.println("Listening for requests at " + server.getURI());
+        new Semaphore(0).acquire();
+    }
+}
+----
+
+The example below bootstraps a `Server` instance on random ports inside a test case and exits when the test case is complete:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+//...
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+}
+----
+
+In the above code we have assembled the classes `Api`, `Movie` and `MovieService` into a virtual archive, then we add that archive into a virtual Tomcat install at the location `webapps/ROOT/WEB-INF/classes`.  When we call `build()` the Tomcat server instance is started in our JVM and will begin serving HTTP requests at the host/port identified by `server.getURI()`
+
+In short, we've bootstrapped a Tomcat server in our JVM that has a very tiny disk footprint; three classes and a handful of default configuration files.
+
+== Running
+
+Were we to run the above Main class or Test Case we'd see output like the following:
+
+[source,bash]
+----
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener deployApplication
+INFO:      org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@2d313c8c
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: REST Application: http://localhost:8080/api        -> org.superbiz.movie.Api@6b2dd3df
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:      Service URI: http://localhost:8080/api/movies -> Pojo org.superbiz.movie.MovieService
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:               GET http://localhost:8080/api/movies ->      List<Movie> getAllMovies()
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:              POST http://localhost:8080/api/movies ->      Movie addMovie(Movie)     
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Deployment of web application directory [/private/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp14966428831095231081dir/apache-tomee/webapps/ROOT] has finished in [1,798] ms
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Starting ProtocolHandler ["http-nio-8080"]
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Server startup in [1877] milliseconds
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Full bootstrap in [3545] milliseconds
+Listening for requests at http://localhost:8080
+----
diff --git a/examples/serverless-tomee-plus/pom.xml b/examples/serverless-tomee-plus/pom.xml
new file mode 100644
index 0000000..6c06365
--- /dev/null
+++ b/examples/serverless-tomee-plus/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.superbiz</groupId>
+  <artifactId>serverless-tomee-plus</artifactId>
+  <version>8.0.5-SNAPSHOT</version>
+
+  <name>TomEE :: Examples :: Serverless Apache TomEE Plus</name>
+  
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <version.tomee>8.0.5-SNAPSHOT</version.tomee>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomee.bom</groupId>
+      <artifactId>tomee-plus</artifactId>
+      <version>${version.tomee}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.5.1</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!--
+  This section allows you to configure where to publish libraries for sharing.
+  It is not required and may be deleted.  For more information see:
+  http://maven.apache.org/plugins/maven-deploy-plugin/
+  -->
+  <distributionManagement>
+    <repository>
+      <id>localhost</id>
+      <url>file://${basedir}/target/repo/</url>
+    </repository>
+    <snapshotRepository>
+      <id>localhost</id>
+      <url>file://${basedir}/target/snapshot-repo/</url>
+    </snapshotRepository>
+  </distributionManagement>
+</project>
diff --git a/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Api.java b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Api.java
new file mode 100644
index 0000000..a7c43d3
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Api.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Movie.java b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Movie.java
new file mode 100644
index 0000000..450959b
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie;
+
+public class Movie {
+
+    private String title;
+    private String director;
+    private String genre;
+    private int id;
+    private int year;
+
+    public Movie() {
+    }
+
+    public Movie(final String title, final String director, final String genre, final int id, final int year) {
+        this.title = title;
+        this.director = director;
+        this.genre = genre;
+        this.id = id;
+        this.year = year;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+
+    public String getDirector() {
+        return director;
+    }
+
+    public void setDirector(final String director) {
+        this.director = director;
+    }
+
+    public String getGenre() {
+        return genre;
+    }
+
+    public void setGenre(final String genre) {
+        this.genre = genre;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(final int id) {
+        this.id = id;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public void setYear(final int year) {
+        this.year = year;
+    }
+}
diff --git a/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/MovieService.java b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/MovieService.java
new file mode 100644
index 0000000..b8acbc2
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
diff --git a/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/Main.java b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/Main.java
new file mode 100644
index 0000000..2f077aa
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/Main.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie;
+
+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());
+    }
+
+
+//    public static void main(String[] args) {
+//        Server.builder()
+//                .home(file -> Stream.of(file.listFiles()).forEach(System.out::println))
+//                .build();
+//    }
+//
+}
diff --git a/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/MovieServiceTest.java b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/MovieServiceTest.java
new file mode 100644
index 0000000..08b5a69
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/MovieServiceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+
+    @Test
+    public void addMovie() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+        final Movie posted = target.path("/api/movies").request()
+                .post(entity(movie, MediaType.APPLICATION_JSON))
+                .readEntity(Movie.class);
+
+        assertEquals("Tom Dey", posted.getDirector());
+        assertEquals("Shanghai Noon", posted.getTitle());
+        assertEquals("Comedy", posted.getGenre());
+        assertEquals(2000, posted.getYear());
+        assertEquals(7, posted.getId());
+    }
+}
diff --git a/examples/serverless-tomee-webprofile/README.adoc b/examples/serverless-tomee-webprofile/README.adoc
new file mode 100644
index 0000000..c1bdbd0
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/README.adoc
@@ -0,0 +1,168 @@
+:index-group: Serverless
+:jbake-type: page
+:jbake-status: status=published
+= Serverless TomEE WebProfile
+
+Apache TomEE can be run as a library inside your JVM with no need for separate processes or a standalone server install.  In this approach we include the right libraries in our project and then bootstrap TomEE using the `Server.Builder` API.
+
+== Include the `tomee-webprofile` dependency
+
+To make things as easy as possible there is just one dependency that will give you a classpath that is 100% identical to your favorite Apache TomEE distribution.  The following dependency will pull give you an environment identical to an Apache TomEE WebProfile binary distribution.
+
+[source,xml]
+----
+<dependency>
+  <groupId>org.apache.tomee.bom</groupId>
+  <artifactId>tomee-webprofile</artifactId>
+  <version>${version.tomee}</version>
+</dependency>
+----
+
+NOTE: The `org.apache.tomee.bom:tomee-webprofile` is actually generated by analyzing the apache-tomee-webprofile-x.y.z.zip, so is guaranteed to be 100% identical making it easy to transition from a zip file to a simple maven dependency.
+
+== Write Regular Code
+
+Here we see a simple JAX-RS API for sending/recieving `Movie` objects as JSON.
+
+[source,java]
+----
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
+----
+
+== Bootstrap TomEE with the Server Builder
+
+A this point we have a Maven project with the right dependencies and some application code in our project.  From here we use the `Server.Builder` API to construct a `Server` instance inside our JVM.
+
+Here we see a simple Main class that bootstraps a `Server` instance on port `8080` and blocks:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+import java.util.concurrent.Semaphore;
+
+public class Main {
+    public static void main(String[] args) throws InterruptedException {
+
+        final Server server = Server.builder()
+                .httpPort(8080)
+                .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+                        .add(Api.class)
+                        .add(Movie.class)
+                        .add(MovieService.class))
+                .build();
+
+        System.out.println("Listening for requests at " + server.getURI());
+        new Semaphore(0).acquire();
+    }
+}
+----
+
+The example below bootstraps a `Server` instance on random ports inside a test case and exits when the test case is complete:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+//...
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+}
+----
+
+In the above code we have assembled the classes `Api`, `Movie` and `MovieService` into a virtual archive, then we add that archive into a virtual Tomcat install at the location `webapps/ROOT/WEB-INF/classes`.  When we call `build()` the Tomcat server instance is started in our JVM and will begin serving HTTP requests at the host/port identified by `server.getURI()`
+
+In short, we've bootstrapped a Tomcat server in our JVM that has a very tiny disk footprint; three classes and a handful of default configuration files.
+
+== Running
+
+Were we to run the above Main class or Test Case we'd see output like the following:
+
+[source,bash]
+----
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener deployApplication
+INFO:      org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@2d313c8c
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: REST Application: http://localhost:8080/api        -> org.superbiz.movie.Api@6b2dd3df
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:      Service URI: http://localhost:8080/api/movies -> Pojo org.superbiz.movie.MovieService
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:               GET http://localhost:8080/api/movies ->      List<Movie> getAllMovies()
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO:              POST http://localhost:8080/api/movies ->      Movie addMovie(Movie)
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Deployment of web application directory [/private/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp14966428831095231081dir/apache-tomee/webapps/ROOT] has finished in [1,798] ms
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Starting ProtocolHandler ["http-nio-8080"]
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Server startup in [1877] milliseconds
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Full bootstrap in [3545] milliseconds
+Listening for requests at http://localhost:8080
+----
diff --git a/examples/serverless-tomee-webprofile/pom.xml b/examples/serverless-tomee-webprofile/pom.xml
new file mode 100644
index 0000000..b778eef
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.superbiz</groupId>
+  <artifactId>serverless-tomee-webprofile</artifactId>
+  <version>8.0.5-SNAPSHOT</version>
+
+  <name>TomEE :: Examples :: Serverless Apache TomEE WebProfile</name>
+  
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <version.tomee>8.0.5-SNAPSHOT</version.tomee>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomee.bom</groupId>
+      <artifactId>tomee-webprofile</artifactId>
+      <version>${version.tomee}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.5.1</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!--
+  This section allows you to configure where to publish libraries for sharing.
+  It is not required and may be deleted.  For more information see:
+  http://maven.apache.org/plugins/maven-deploy-plugin/
+  -->
+  <distributionManagement>
+    <repository>
+      <id>localhost</id>
+      <url>file://${basedir}/target/repo/</url>
+    </repository>
+    <snapshotRepository>
+      <id>localhost</id>
+      <url>file://${basedir}/target/snapshot-repo/</url>
+    </snapshotRepository>
+  </distributionManagement>
+</project>
diff --git a/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Api.java b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Api.java
new file mode 100644
index 0000000..320fddc
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Api.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Movie.java b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Movie.java
new file mode 100644
index 0000000..b5b02df
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+public class Movie {
+
+    private String title;
+    private String director;
+    private String genre;
+    private int id;
+    private int year;
+
+    public Movie() {
+    }
+
+    public Movie(final String title, final String director, final String genre, final int id, final int year) {
+        this.title = title;
+        this.director = director;
+        this.genre = genre;
+        this.id = id;
+        this.year = year;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+
+    public String getDirector() {
+        return director;
+    }
+
+    public void setDirector(final String director) {
+        this.director = director;
+    }
+
+    public String getGenre() {
+        return genre;
+    }
+
+    public void setGenre(final String genre) {
+        this.genre = genre;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(final int id) {
+        this.id = id;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public void setYear(final int year) {
+        this.year = year;
+    }
+}
diff --git a/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/MovieService.java b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
new file mode 100644
index 0000000..d12ef58
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+    private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void construct(){
+        this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+        this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+        this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+        this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+        this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+        this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+    }
+    @GET
+    public List<Movie> getAllMovies() {
+        return new ArrayList<>(store.values());
+    }
+
+    @POST
+    public Movie addMovie(final Movie newMovie) {
+        store.put(newMovie.getId(), newMovie);
+        return newMovie;
+    }
+
+}
diff --git a/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/Main.java b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/Main.java
new file mode 100644
index 0000000..df2b47e
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/Main.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+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))
+                .build();
+
+        System.out.println("Listening for requests at " + server.getURI());
+    }
+}
diff --git a/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java
new file mode 100644
index 0000000..23e1274
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.superbiz.movie.wp;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+    private static URI serverURI;
+
+    @BeforeClass
+    public static void setup() {
+        // Add any classes you need to an Archive
+        // or add them to a jar via any means
+        final Archive classes = Archive.archive()
+                .add(Api.class)
+                .add(Movie.class)
+                .add(MovieService.class);
+
+        // Place the classes where you would want
+        // them in a Tomcat install
+        final Server server = Server.builder()
+                // This effectively creates a webapp called ROOT
+                .add("webapps/ROOT/WEB-INF/classes", classes)
+                .build();
+
+        serverURI = server.getURI();
+    }
+
+    @Test
+    public void getAllMovies() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+        assertEquals(6, movies.length);
+
+        final Movie movie = movies[1];
+        assertEquals("Todd Phillips", movie.getDirector());
+        assertEquals("Starsky & Hutch", movie.getTitle());
+        assertEquals("Action", movie.getGenre());
+        assertEquals(2004, movie.getYear());
+        assertEquals(2, movie.getId());
+    }
+
+    @Test
+    public void addMovie() {
+        final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+        final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+        final Movie posted = target.path("/api/movies").request()
+                .post(entity(movie, MediaType.APPLICATION_JSON))
+                .readEntity(Movie.class);
+
+        assertEquals("Tom Dey", posted.getDirector());
+        assertEquals("Shanghai Noon", posted.getTitle());
+        assertEquals("Comedy", posted.getGenre());
+        assertEquals(2000, posted.getYear());
+        assertEquals(7, posted.getId());
+    }
+}