Creating Uber JAR with Payara Micro 5

Uncategorized

Payara Micro allows you to run web applications in a self-contained and easy way. Since the release of the Payara Server in May 2016, there is a simple way to generate an “Uber” JAR that bundles the contents of a WAR file and the classes and resources that compose Payara Micro!

Note that this “Uber” Jar is not the best way to run your application in a Docker container as it requires an update of the entire binary for each small code change you make in the application. A better solution is just to start a Payara Micro Instance and point to the application that needs to be installed. More information can be found on our Payara Micro Docker Image documentation.

(last updated 06/04/2021)

Implementation

First, generate a web application using traditional means (like Maven for example). Then, deploy this application with Payara Micro with the –outputUberJar option enabled to generate the resulting JAR file:

java -jar payara-micro-5.2021.1.jar --deploy test-app.war --outputUberJar test-app.jar

You will get an output like the following:

Apr 06, 2021 9:09:47 AM fish.payara.micro.impl.UberJarCreator buildUberJar
INFO: Building Uber Jar... test-app.jar
Apr 06, 2021 9:09:48 AM fish.payara.micro.impl.UberJarCreator buildUberJar
INFO: Built Uber Jar basic-servlet.jar in 450 (ms)

And finally, with this Uber jar created, you can just run the application using a simple Java command:

java -jar test-app.jar

With this, the Payara Micro instance will startup and deploy the original web application!  

Now, what happens if you want to change the HTTP port this application uses (8080 by default)? Or disable the clustering capabilities? You can pass all compatible Payara Micro configuration options for the Uber jar generation, and when the application is run these options will be used to configure the server instance:

java -jar payara-micro-5.2021.1.jar --deploy test-app.war --outputUberJar test-app.jar --port 9898 --noCluster

But what if we want to configure an application instance HTTP port and/or cluster configuration at runtime instead? Fear not, we can still pass these properties as arguments when running the application’s JAR:

java -jar test-app.jar --port 10080 --noCluster

Also, we are not limited to bundling only one application in this Uber JAR, since we can package more applications by using the –deploy option multiple times:

java -jar payara-micro-5.2021.1.jar --deploy test-app-1.war --deploy test-app-2.war --outputUberJar test-app.jar

And when you start the packaged applications in this JAR, the server will inform you how many applications were deployed:

[2021-04-06T09:56:53.923+0000] [] [INFO] [] [PayaraMicro] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1617693676410] [levelValue: 800] Deployed 2 archive(s)

With this you can create self-contained environments for your applications and deploy them easily! Since Payara Micro is small in size, packaging and moving the resulting JAR is cost-effective and saves time.

The Maven Way

Usually, when creating self-contained applications; one of the most common scenarios is to create an Uber JAR using Maven, generally through the use of the shade plugin. When using the Payara Micro Maven plugin, this task becomes very easy and you can specify all the command line options you need in the Maven configuration. The following example generates the Uber JAR file in the package phase of the Maven lifecycle:<plugin>
<groupId>fish.payara.maven.plugins</groupId>
<artifactId>payara-micro-maven-plugin</artifactId>
<version>1.3.0</version>
<configuration>
<payaraVersion>5.2021.1</payaraVersion>
<deployWar>true</deployWar>
<commandLineOptions>
<option>
<key>–autoBindHttp</key>
</option>
</commandLineOptions>
<contextRoot>/</contextRoot>
</configuration>
<executions>
     
<execution>
        
<goals>
           
<goal>bundle</goal>
        
</goals>
     
</execution>
</executions>
</plugin>

With this plugin declaration, we configure the execution of the bundle goal which runs the Payara Micro Uber JAR creation. We can specify multiple Command Line options and configuration parameters like the contact root. All the configuration parameters are described in our document of the plugin.

Dockerizing our Uber JAR

{{cta(‘a1fd6946-f37d-4a1d-9f83-58a0f232f17e’)}}

What if developers want to create a Docker container based on a Payara Micro Uber JAR? Although there are multiple options for this scenario, the easiest one is to use a Java based Docker image to acquire the Uber JAR and execute it. For example, we can structure the following Dockerfile:

FROM azul/zulu-openjdk-alpine:8

ENV APP_LOCATION ./test-app.jar
ENV APP_NAME application.jar

ADD $APP_LOCATION $APP_NAME
RUN chmod +x $APP_NAME

EXPOSE 8080

ENTRYPOINT java -jar $APP_NAME

And build a new image:

docker build -t payara-uber-jar .

Notice that we are using the azul:zulu-openjdk-alpine:8 as a base image for our example. This is the Zulu Java 8 image based on the Alpine Linux Operating system, which is a very small sized distribution since we want this container to be as light as possible (this is the same base image we use for our official Payara Micro Docker image). We are using the Dockerfile ADD instruction to download our Uber JAR from an external source (in this case an uberjar in the same directory as th Dockerfile) and then simply setting our endpoint for this container to run our test application with the downloaded Uber JAR.

To start this container, we would simply execute the following command:

docker run -d -p 8080:8080 --name uber-jar payara-uber-jar

Note however that using an Uber JAR with Docker images is not efficient  and is a bad practice. With every change in your code, you need to build the Uber JAR and create a new Docker image where not only the application changes are picked up but a much larger JAR file including the unchanged Payara Micro code.

A better solution is just to start a Payara Micro Instance and point to the application that needs to be installed. More information can be found on our Payara Micro Docker Image documentation.

Conclusion

Payara Micro introduces a new set of possibilities for application developers, and with the advent of complex concepts such as Microservices and DevOps, the ability to create a self-contained JAR that can run the server and application at the same time is something many developers need.

Java developers should feel at ease, since with this approach Payara Server can be easily integrated with many continuous integration workflows.

Comments (5)

Post a comment

Your email address will not be published. Required fields are marked *

Payara needs the contact information you provide to us to contact you about our products and services. You may unsubscribe from these communications at any time. For information on how to unsubscribe, as well as our privacy practices and commitment to protecting your privacy, please review our Legal & Privacy Policy.

  1. Luis C Lombana

    Thanks for the article. Really interesting, seems very helpful to automatize various task for simple deployments in test and development environments

  2. AbdulBasit KABIR

    Nice article. Very helpful.
    When I start the uberJar, it deploys my application with context set as the name of the war (e.g test-app) even though it has a context defined in web.xml. But when I just deploy with payara micro without creating the uber Jar, the context is as set in web.xml.
    How can I get it deployed in the uber jar at context set in web.xml?

    1. Fabio Turizo

      Thanks for reading the article AbdulBasit. Regarding the context root of applications packaged into Uber Jars, the context-root of the application will always be the name of the application WAR file that is deployed. For example if you package the test.war application into the test-app.jar Uber JAR with the default ports, then you can access it under:

      http://localhost:8080/test/

      This will always happen, regardless of whether the application has specified a context-root definition in the glassfish-web.xml deployment descriptor. There’s a special case however. If you deploy an application file with the name ROOT.war, then the application’s context root will be the root of the application’s server.

      Hope this answers your question!

  3. Manoel Campos

    Thanks for the post. I’m wondering what is the entry point class for other payara distributions (such as web and all). For Payara Micro it’s fish.payara.micro.PayaraMicro

  4. Fabio Turizo

    Manoel, that is an interesting question. The entrypoint for Payara Server is actually a chain of classes that start with the ASMain (https://github.com/payara/Payara/blob/70e98fbe94cd3bb72b4e1b6f88f87f9eedab459e/nucleus/core/bootstrap/src/main/java/com/sun/enterprise/glassfish/bootstrap/ASMain.java) class. This class will, in turn, call the GlassfishMain class, and so forth until reaching the AppServerStartup class, that will handle the startup of a new server instance.

Related Posts

Blue background with coral and fish. Left text: 'MONTHLY CATCH'. Right: laptop screen with tech tabs and Payara Community logo. 3 minutes
Community

The Payara Monthly Catch -September 2025

Welcome aboard the September issue of The Monthly Catch! With summer holidays wrapping up, the Java world is back […]

4 minutes
Uncategorized

Leading the Way: Payara Platform Community 7 Beta Now Fully Jakarta EE 11 Certified

We’re excited to announce that Payara Platform Community 7 Beta application server is now fully certified as Jakarta EE 11 […]

Understanding the Security Issues of Aging Middleware 6 minutes
Community

Boost Developer Productivity with Payara Server Maven Plugin + AI Agent

Managing Payara Server Just Got Smarter  Imagine managing your Jakarta EE applications not just with Maven goals, but by […]