At Tomitribe we are active stakeholders on projects like Apache TomEE, Eclipse MicroProfile and Eclipse JakartaEE and provide Enterprise Support for these and other Open Source projects like Apache Tomcat & Active MQ.

In this article, we will cover how developers can create a microservice with Java using the Eclipse MicroProfile specifications with the DevOps friendly application server, Apache TomEE.

If MicroProfile is a topic you want to learn more about, we have many other blog posts covering the basics of Eclipse MicroProfile with details of each of the specifications along with examples. The official Apache TomEE project website also has a series of example projects built with Java, Maven and Eclipse MicroProfile.

MicroProfile meets TomEE

By now, you should be familiar with the MicroProfile specifications illustrated below, but it’s important to highlight that TomEE MicroProfile is based on TomEE JAX-RS. As a result, many of the Jakarta EE (formally Java EE) technologies in TomEE already support MicroProfile out of the box.

Image 1: MicroProfile specifications.
Image 2 lists the twelve Jakarta EE specifications that you can use to boost MicroProfile-based microservices. In the following sections we will review different techniques to create your microservices from scratch, the only requirement you will need to have on your computer it’s Java and Maven installed.

Image 2: TomEE JAX-RS specifications

Create a microservice using TomEE tomee-webapp-archetype

In order to create a project using the Tomee webapp archetype, execute the following command in a console:

$ mvn archetype:generate -B -DarchetypeGroupId=org.apache.tomee.maven -DarchetypeArtifactId=tomee-webapp-archetype -DarchetypeVersion=8.0.0-M2 -DgroupId=superbiz.foo -DartifactId=book-microservice

The project structure contains the following specifications and technologies out of the box to give you a sample of what you can do with a vanilla JakartaEE project:

  • Stateless EJB: BookService.java
  • Java API: Book.java, persistence.xml
  • CDI Bean: BookBean.java
  • JSF: book.xhtml and result.xhtml
  • Arquillian.xml: Commented out for you to decide to use it or not later in your integration tests.

book-microservice$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── superbiz
    │   │       └── foo
    │   │           ├── application
    │   │           │   └── BookService.java
    │   │           ├── entities
    │   │           │   └── Book.java
    │   │           └── presentation
    │   │               └── BookBean.java
    │   ├── resources
    │   │   └── META-INF
    │   │       └── persistence.xml
    │   └── webapp
    │       ├── WEB-INF
    │       │   ├── beans.xml
    │       │   └── faces-config.xml
    │       ├── book.xhtml
    │       ├── index.jsp
    │       └── result.xhtml
    └── test
        └── resources
            └── arquillian.xml

14 directories, 11 files

To add MicroProfile capabilities to our project we need to update the <dependencies< section in the pom.xml by adding the MicroProfile dependency with a provided scope to indicate that our application will rely on TomEE to provide the necessary libs:

<dependency>
    <groupId>org.eclipse.microprofile</groupId>
    <artifactId>microprofile</artifactId>
    <version>2.0.1</version>
    <type>pom</type>
    <scope>provided</scope>
</dependency>

Finally, we need to update the <configuration> from the tomee-maven-plugin. We need to include the <tomeeClassifier> to declare the microprofile TomEE version we want to use with the plugin.

<plugin>
    <groupId>org.apache.tomee.maven</groupId>
    <artifactId>tomee-maven-plugin</artifactId>
    <version>8.0.0-M2</version>
    <configuration>
    	<context>ROOT</context>
	<tomeeClassifier>microprofile</tomeeClassifier>
    </configuration>
</plugin>

On a terminal you can build and run the project using the Tomee Maven plugin:

$ mvn clean package tomee:run

You will notice that the MicroProfile metrics endpoints appear on the startup log:

INFO      Service URI: http://localhost:8080/health
INFO     GET http://localhost:8080/metrics/{registry}/{metric}
INFO     OPTIONS http://localhost:8080/metrics/{registry}
INFO     OPTIONS http://localhost:8080/metrics/{registry}/{metric}
Starting ProtocolHandler ["http-nio-8080"]
Starting ProtocolHandler ["ajp-nio-8009"]
Server startup in 3964 ms

When the Maven command is finished you can visit the URL http://localhost:8080/metrics and visualize the corresponding server metrics:

# TYPE base:classloader_total_loaded_class_count counter
base:classloader_total_loaded_class_count 9898.0
# TYPE base:thread_count counter
base:thread_count 42.0
# TYPE base:classloader_current_loaded_class_count counter
base:classloader_current_loaded_class_count 9898.0
# TYPE base:jvm_uptime_seconds gauge
base:jvm_uptime_seconds 0.05792
# TYPE base:gc_ps_mark_sweep_count counter
base:gc_ps_mark_sweep_count 2.0
# TYPE base:gc_ps_scavenge_count counter
base:gc_ps_scavenge_count 8.0
# TYPE base:memory_committed_heap_bytes gauge
base:memory_committed_heap_bytes 3.62807296E8
# TYPE base:thread_max_count counter
base:thread_max_count 42.0
# TYPE base:cpu_available_processors gauge
base:cpu_available_processors 4.0
# TYPE base:thread_daemon_count counter
base:thread_daemon_count 41.0
# TYPE base:classloader_total_unloaded_class_count counter
base:classloader_total_unloaded_class_count 9898.0
# TYPE base:memory_max_heap_bytes gauge
base:memory_max_heap_bytes 3.817865216E9
# TYPE base:gc_ps_mark_sweep_time_seconds gauge
base:gc_ps_mark_sweep_time_seconds 2.25E-4
# TYPE base:memory_used_heap_bytes gauge
base:memory_used_heap_bytes 7.280616E7
# TYPE base:gc_ps_scavenge_time_seconds gauge
base:gc_ps_scavenge_time_seconds 2.14E-4
# TYPE vendor:start_time counter
vendor:start_time 1.565888981255E12

Remember that instead of the Prometheus format you can also request the JSON format by adding the Accept request header with the value application/json.

{
  "application": {
    
  },
  "vendor": {
    "startTime": 1565748321261
  },
  "base": {
    "classloader.totalLoadedClass.count": 9816,
    "thread.count": 42,
    "classloader.currentLoadedClass.count": 9816,
    "jvm.uptime": 29459,
    "gc.PS MarkSweep.count": 2,
    "thread.max.count": 42,
    "memory.committedHeap": 363855872,
    "gc.PS Scavenge.count": 8,
    "cpu.availableProcessors": 4,
    "thread.daemon.count": 41,
    "classloader.totalUnloadedClass.count": 9816,
    "memory.maxHeap": 3817865216,
    "memory.usedHeap": 70708544,
    "gc.PS MarkSweep.time": 106,
    "gc.PS Scavenge.time": 94
  }
}

To quit the microservice type on the terminal crtl+c

Create a microservice using MicroProfile Starter Website

The MicroProfile community offers the MicroProfile Starter website to build Maven basic projects with or without examples.To create a new project you can visit the URL: https://start.microprofile.io/ and fill out your project details. For this example we will use the following:

  • groupId: superbiz.foo
  • artifactId: movie-microservice
  • MicroProfile versión: 2.0
  • MicroProfile server: Apache TomEE 8.0.0-M2
  • Example of specifications: Deselect everything except for “Config” ( MicroProfile configuration).

After clicking on the DOWNLOAD button, a movie-microservice.zip file is downloaded to your computer. After extracting the zip file you will see that the structure of the maven based project is pretty similar to what we got by using the Tomee web app archetype:


movie-microservice$ tree
.
├── pom.xml
├── readme.md
└── src
    ├── main
    │   ├── java
    │   │   └── superbiz
    │   │       └── foo
    │   │           └── movie
    │   │               └── microservice
    │   │                   ├── HelloController.java
    │   │                   ├── MoviemicroserviceRestApplication.java
    │   │                   └── config
    │   │                       └── ConfigTestController.java
    │   ├── resources
    │   │   ├── META-INF
    │   │   │   └── microprofile-config.properties
    │   │   └── publicKey.pem
    │   └── webapp
    │       ├── WEB-INF
    │       │   └── beans.xml
    │       └── index.html
    └── test
        └── java

14 directories, 9 files

This time the project structure contains the following technologies and specifications:

  • Java JAX-RS: HelloController.java and MoviemicroserviceRestApplication.java
  • JAX-RS endpoint with MicroProfile Config injection: ConfigTestController.java
  • MicroProfile config configuration file: META-INF/microprofile-config.properties

There is one important difference in the project pom.xml file compared against to the one used with the Tomee webapp archetype, the project generated by the MicroProfile Starter already contains the maven MicroProfile dependency and tomeeClassifier in the maven-plugin configuration.

On a terminal you can build and run the movie-microservice project using the Tomee Maven plugin:

Make sure you quit the microservice we created previously before proceeding.

$ mvn clean package tomee:run

You will notice that the MicroProfile metrics endpoints appear on the startup log again but now with the application context as prefix:

INFO     Service URI: http://localhost:8080/data/health
INFO     GET http://localhost:8080/data/metrics/{registry}/{metric}
INFO     OPTIONS http://localhost:8080/data/metrics/{registry}
INFO     OPTIONS http://localhost:8080/data/metrics/{registry}/{metric}
Starting ProtocolHandler ["http-nio-8080"]
Starting ProtocolHandler ["ajp-nio-8009"]
Server startup in 3964 ms

You can visit now you the URL http://localhost:8080/data/metrics and visualize the corresponding server metrics (shown below in the JSON format):

{
  "application": {
    
  },
  "vendor": {
    "startTime": 1565794360335
  },
  "base": {
    "classloader.totalLoadedClass.count": 9153,
    "thread.count": 39,
    "classloader.currentLoadedClass.count": 9153,
    "jvm.uptime": 106749,
    "gc.PS MarkSweep.count": 2,
    "thread.max.count": 39,
    "memory.committedHeap": 353370112,
    "gc.PS Scavenge.count": 8,
    "cpu.availableProcessors": 4,
    "thread.daemon.count": 38,
    "classloader.totalUnloadedClass.count": 9153,
    "memory.maxHeap": 3817865216,
    "memory.usedHeap": 103169320,
    "gc.PS MarkSweep.time": 124,
    "gc.PS Scavenge.time": 118
  }
}

You also can visit the endpoint http://localhost:8080/data/config/injected that shows the value injected in the JAX-RS endpoint using MicroProfile config:

$ curl http://localhost:8080/data/config/injected

Config value as Injected by CDI Injected value

Create a microservice using MicroProfile Starter REST API

MicroProfile Starter also offers a REST API that you can use to create a new project with the parameters and options available on the website version.

To create the song-microservice with the same structure as the movie-microservice you need to do a GET request with the following parameters:

$ curl -O -J 'https://start.microprofile.io/api/1/project?supportedServer=TOMEE&groupId=superbiz.foo&artifactId=songs-microservice&selectedSpecs=CONFIG'

Curl -O -J tells curl to save the zip file in the current directory.

The songs-microservice.zip gets downloaded and the project structure is the same we got for the movie-microservice:

songs-microservice$ tree
.
├── pom.xml
├── readme.md
└── src
    ├── main
    │   ├── java
    │   │   └── superbiz
    │   │       └── foo
    │   │           └── songs
    │   │               └── microservice
    │   │                   ├── HelloController.java
    │   │                   ├── SongsmicroserviceRestApplication.java
    │   │                   └── config
    │   │                       └── ConfigTestController.java
    │   ├── resources
    │   │   ├── META-INF
    │   │   │   └── microprofile-config.properties
    │   │   └── publicKey.pem
    │   └── webapp
    │       ├── WEB-INF
    │       │   └── beans.xml
    │       └── index.html
    └── test
        └── java

14 directories, 9 files

On a terminal you can build and run the songs-microservice project using the Tomee Maven plugin:

Again, make sure you quit the microservice we created previously before proceeding.

$ mvn clean package tomee:run

You can visit now you the URL http://localhost:8080/data/metrics and visualize the corresponding server metrics.

Contribute and join the conversation

Both the Tomee webapp archetype and MicroProfile Starter are OpenSource projects. You can join the discussions about these projects and collaborate on both code bases by visiting:

Conclusion

In this article, we covered how you can create a MicroProfile project from scratch with TomEE DevOps features using maven archetypes and rest endpoints. Now, it is easy to take advantage of TomEE’s Jakarta EE (formerly Java EE) capabilities in your newly created project and integrate MicroProfile in your existing projects.

Cesar Hernandez

Cesar Hernandez

César Hernández is a Senior Software Engineer at Tomitribe with experience in Enterprise Java Applications. He is a Java Champion, Duke's Choice Award winner, Eclipse Committer, Open Source advocate, teacher, and public speaker. When César is away from a computer, he enjoys spending time with his family, traveling and playing music with the Java Community Band, The Null Pointers. Follow Cesar on twitter @CesarHgt
CesarHgt

Leave a Reply