Apache TomEE 8 introduced a new Microprofile distribution which is great if you are still deploying in a server but if you moved Docker or an equivalent technology then it is not the best you can do.

The first idea you get when you want to build a docker with TomEE is to use tomee:exec maven plugin but it actually starts a java program which will extract a full TomEE distribution from its own jar and then launch and wait it. It is not what you want in most cases in a (Docker) container.

So is TomEE that bad and I have to migrate to another server? Actually not and if you already got some experience with Apache Meecrowave, TomEE can be pretty close and smooth but it is not that communicated today.

The trick is to use TomEE embedded which allows to deploy a classpath, then everything becomes smooth.

In the context of this post we will just see how to update your project to get a TomEE Embedded and Microprofile, next one will create a Docker image from this setup.

The first step is to import tomee-embedded and remove what you don't need which could be there by default - indeed the exclusion step is optional. In our case we will remove JSF, some JSP related dependencies since we target Microprofile we will not need it, websockets and JAX-WS related dependencies:

<dependency>
  <groupId>org.apache.tomee</groupId>
  <artifactId>tomee-embedded</artifactId>
  <version>8.0.0-M2</version>
  <scope>runtime</scope>
  <exclusions>
    <exclusion>
      <groupId>org.apache.myfaces.core</groupId>
      <artifactId>myfaces-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.tomee</groupId>
      <artifactId>tomee-myfaces</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.myfaces.core</groupId>
      <artifactId>myfaces-impl</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-jstlel</artifactId>
    </exclusion>
    <exclusion>
      <groupId>xalan</groupId>
      <artifactId>xalan</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.eclipse.jdt.core.compiler</groupId>
      <artifactId>ecj</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.tomee</groupId>
      <artifactId>tomee-webservices</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-websocket</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Note: if you check in detail you will see some JSP or EL dependencies are still there but today TomEE does not enable to remove them without breaking some integrations, this is can some easy newbie task if you are motivated for it, just send a small mail on the user list and create a ticket on TOMEE project.

The other thing to take care is the javaee-api jar. In this case I didn't exclude it but if you set it in your project already you can want to exclude it. It depends if you do that dependency management in your business module or a build module. The main difference being that in a business project you don't want TomEE stack to be in compile scope but you need the javaee-api at compile time.

At that stage we have a "JAX-RS" TomEE stack available. The next step is to add Microprofile stack. The fastest to do it is to import Apache Geronimo Microprofile aggregator:

<dependency>
  <groupId>org.apache.geronimo</groupId>
  <artifactId>geronimo-microprofile-aggregator</artifactId>
  <version>1.0.2</version>
  <type>pom</type>
  <scope>runtime</scope>
</dependency>

This imports a full Microprofile stack and does not need much customization to run out of the box!

If you run your application - let's assume I cerated a /demo endpoint - with these two dependencies you will see:

INFOS - REST Application: http://localhost:8080/                            -> org.apache.openejb.server.rest.InternalApplication@59c43561
INFOS -      Service URI: http://localhost:8080/demo                        -> Pojo com.github.rmannibucau.demo.SimpleEndpoint
INFOS -               GET http://localhost:8080/demo                        ->      String date()
INFOS -      Service URI: http://localhost:8080/health                      -> Pojo org.apache.geronimo.microprofile.common.jaxrs.HealthChecksEndpoint
INFOS -               GET http://localhost:8080/health                      ->      Response getChecks()
INFOS -      Service URI: http://localhost:8080/health                      -> Pojo org.apache.geronimo.microprofile.impl.health.cdi.CdiHealthChecksEndpoint
INFOS -               GET http://localhost:8080/health                      ->      Response getChecks()
INFOS -      Service URI: http://localhost:8080/metrics                     -> Pojo org.apache.geronimo.microprofile.metrics.common.jaxrs.MetricsEndpoints
INFOS -               GET http://localhost:8080/metrics                     ->      Object getJson(SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics                     ->      String getText(SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}          ->      Object getJson(String, SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}          ->      String getText(String, SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}/{metric} ->      Object getJson(String, String, SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}/{metric} ->      String getText(String, String, SecurityContext, UriInfo)
INFOS -           OPTIONS http://localhost:8080/metrics/{registry}          ->      Object getMetadata(String, SecurityContext, UriInfo)
INFOS -           OPTIONS http://localhost:8080/metrics/{registry}/{metric} ->      Object getMetadata(String, String, SecurityContext, UriInfo)
INFOS -      Service URI: http://localhost:8080/metrics                     -> Pojo org.apache.geronimo.microprofile.metrics.jaxrs.CdiMetricsEndpoints
INFOS -               GET http://localhost:8080/metrics                     ->      Object getJson(SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics                     ->      String getText(SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}          ->      Object getJson(String, SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}          ->      String getText(String, SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}/{metric} ->      Object getJson(String, String, SecurityContext, UriInfo)
INFOS -               GET http://localhost:8080/metrics/{registry}/{metric} ->      String getText(String, String, SecurityContext, UriInfo)
INFOS -           OPTIONS http://localhost:8080/metrics/{registry}          ->      Object getMetadata(String, SecurityContext, UriInfo)
INFOS -           OPTIONS http://localhost:8080/metrics/{registry}/{metric} ->      Object getMetadata(String, String, SecurityContext, UriInfo)
INFOS -      Service URI: http://localhost:8080/openapi                     -> Pojo org.apache.geronimo.microprofile.openapi.jaxrs.OpenAPIEndpoint
INFOS -               GET http://localhost:8080/openapi                     ->      OpenAPI get()
INFOS - Deployed Application(path=)

In other words, Microprofile is active, TomEE is there and you deployed your classpath properly :).

Simple, isn't it?

Next post will take that application and put it in a docker in a few second!

 

From the same author:

In the same category: