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