Oracle Developers
Published in

Oracle Developers

Using Payara Micro to run Java EE based Microservices

This blog shows you how you can use Payara Micro to build a Java EE based microservice.

Overview

Payara Micro?

Payara Micro is a Java EE based solution for building microservice style applications. Let’s expand on this a little bit

  • Java EE: Payara Micro supports the Java EE Web Profile standard along with additional support for other specifications which are not a part of the Web Profile (e.g. Batch, Concurrency Utilities etc.)
  • It’s a library: Available as a JAR file which encapsulates all these features

Development model

Payara Micro offers you the choice of multiple development styles…

  • WAR: package your Java EE application a WAR file and launch it with Payara Micro using java –jar payara-micro-<version>.jar — deploy mystocks.war
  • Embedded mode: because it’s a library, it can be embedded within your Java applications using its APIs
  • Uber JAR: Use the Payara Micro Maven support along with the exec plugin to package your WAR along with the Payara Micro library as a fat JAR

We will use the fat JAR technique in the sample application presented in the blog

Benefits

Some of the potential benefits are as follows

  • Microservices friendly: gives you the power of Java EE as a library, which can be easily used within applications, packaged in flexible manner (WAR + JAR or just a fat JAR) and run in multiple environments such as PaaS , container based platforms
  • Leverage Java EE skill set: continue using your expertise on Java EE specifications like JAX-RS, JPA, EJB, CDI etc.

About the sample application

It is a vanilla Java EE application which uses the following APIs — JAX-RS, EJB, CDI and WebSocket. It helps keep track of stock prices of NYSE scrips.

  • Users can check the stock price of a scrip (listed on NASDAQ) using a simple REST interface
  • Real time price tracking is also available — but this is only available for Oracle (ORCL)

Here is a high level diagram and some background context

  • an EJB scheduler fetches (ORCL) periodically fetches stock price, fires CDI events which are recevied by the WebSocket component (marked as a CDI event observer) and connected clients are updated with the latest price
  • the JAX-RS REST endpoint is used to fetch price for any stock on demand — this is a typical request-response based HTTP interaction as opposed to the bi-directional, full-duplex WebSocket interaction

Code

Let’s briefly look at the relevant portions of the code (import statements omitted for brevity)

RealTimeStockTicker.java

StockDataEventQualifier.java

/** Custom CDI qualifier to stamp CDI stock price CDI events **/ @Qualifier 
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE}) public @interface StockDataEventQualifier { }

StockPriceScheduler.java

RESTConfig.java

/** * JAX-RS configuration class * */ 
@ApplicationPath("api")
public class RESTConfig extends Application{}

StockDataParser.java

A note on packaging

As mentioned earlier, from a development perspective, it is a typical WAR based Java EE application which is packaged as a fat JAR along with the Payara Micro container

Notice how the container is being packaged with the application rather than the application being deployed into a container

The Java EE APIs are only needed for compilation (scope = provided) since they are present in the Payara Micro library

<dependency> 
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>

Using the Maven plugin to produce a fat JAR

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<dependencies>
<dependency>
<groupId>fish.payara.extras</groupId>
<artifactId>payara-micro</artifactId>
<version>4.1.1.164</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>payara-uber-jar</id>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>fish.payara.micro.PayaraMicro</mainClass>
<arguments>
<argument> — deploy</argument>
<argument>${basedir}/target/${project.build.finalName}.war</argument>
<argument> — outputUberJar</argument>
<argument>${basedir}/target/${project.build.finalName}.jar</argument>
</arguments>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>fish.payara.extras</groupId>
<artifactId>payara-micro</artifactId>
</executableDependency>
</configuration>
</execution>
</executions>
</plugin>

Now to deploy this, we will leverage the following services on Oracle Cloud:

  • Oracle Developer Cloud service: to host the code (Git repo), provide Continuous Integration & Continuous Deployment capabilities (thanks to its integration with other Oracle PaaS services)
  • Oracle Application Container Cloud service: scalable aPaaS for running our Java EE microservice

Setting up Continuous Integration & Deployment

The below sections deal with the configurations to made within Oracle Developer Cloud service

Project & code repository creation

Please refer to the Project & code repository creation section in the Tracking JUnit test results in Developer Cloud service blog or check the product documentation for more details

Configure source code in Git repository

Push the project from your local system to your Developer Cloud Git repo you just created. We will do this via command line and all you need is Git client installed on your local machine. You can use Git or any other tool of your choice

cd <project_folder> git init  git remote add origin <developer_cloud_git_repo>  
//e.g. https://john.doe@developer.us.oraclecloud.com/developer007-foodomain/s/developer007-foodomain-project_2009/scm/sample.git
git add . git commit -m "first commit" git push -u origin master //Please enter the password for your Oracle Developer Cloud account when prompted

Configure build

Create a New Job

Select JDK

Continuous Integration (CI)

Choose Git repository

Set build trigger — this build job will be triggered in response to updated within the Git repository (e.g. via git push)

Add build steps

  • A Maven Build step — to produce the WAR and the fat JAR
  • An Execute Shell step — package up the application JAR along with the required deployment descriptor (manifest.json required by Application Container cloud)

Here is the command for your reference

zip -j accs-payara-micro.zip target/mystocks.jar manifest.json

The manifest.json is as follows

{
“runtime”: {
“majorVersion”: “8”
},
“command”: “java -jar mystocks.jar — port $PORT — noCluster”,
“release”: {
“build”: “23022017.1202”,
“commit”: “007”,
“version”: “0.0.1”
},
“notes”: “Java EE on ACC with Payara Micro”
}

Activate a post build action to archive deployable zip file

Execute Build

Before configuring deployment, we need to trigger the build in order to produce the artifacts which can be referenced by the deployment configuration

After the build is complete, you can

  • Check the build logs
  • Confirm archived artifacts

Logs

Artifacts

Continuous Deployment (CD) to Application Container Cloud

Create a New Confguration for deployment

  • Enter the required details and configure the Deployment Target
  • Configure the Application Container Cloud instance
  • Configure Automatic deployment option on the final confirmation page

You’ll end up with the below configuration

Confirmation screen

Check your application in Application Container Cloud

Test the CI/CD flow

Make some code changes and push them to the Developer Cloud service Git repo. This should

  • Automatically trigger the build, which once successful will
  • Automatically trigger the deployment process, and
  • Redeploy the new application version to Application Container Cloud

Test the application

I would recommend using the client which can be installed into Chrome browser as a plugin — Simple WebSocket Client

That’s all for this blog post..

The views expressed in this post are my own and do not necessarily reflect the views of Oracle

--

--

Aggregation of articles from Oracle engineers, Groundbreaker Ambassadors, Oracle ACEs, and Java Champions on all things Oracle technology. The views expressed are those of the authors and not necessarily of Oracle.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Abhishek Gupta

Principal Developer Advocate at AWS | I ❤️ Databases, Go, Kubernetes