DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

How are you handling the data revolution? We want your take on what's real, what's hype, and what's next in the world of data engineering.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

SBOMs are essential to circumventing software supply chain attacks, and they provide visibility into various software components.

Related

  • How To Use AzureSignTool to Sign Executables With Azure DevOps
  • Build a Java Backend That Connects With Salesforce
  • Build Even Faster Quarkus Applications With fast-jar
  • Deploy Spring Boot Apps From Jar to War

Trending

  • Self-Supervised Learning Techniques
  • Kubernetes Admission Controllers: Your First Line of Defense
  • How Predictive Analytics Became a Key Enabler for the Future of QA
  • Serverless vs Containers: Choosing the Right Architecture for Your Application

Grails Goodness: Creating A Fully Executable JAR

You can use Grails 3 to create a fully executable JAR file without having to use the java -jar CL command. Find out how to do it here.

By 
Hubert Klein Ikkink user avatar
Hubert Klein Ikkink
·
Jun. 23, 16 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
9.0K Views

Join the DZone community and get the full member experience.

Join For Free

With Grails 3 we can create a so-called fat jar or war file. To run our application, we only have to use java -jar followed by our archive file name, and the application starts. Another option is to create a fully executable jar or war file, which adds a shell script in front of the jar or war file so we can immediately run the jar or war file. We don't have to use java -jar to run our Grails application any longer. The fully executable JAR file can only run on Unix-like systems and it is ready to be used as service using init.d or systemd.

Image title

To create a fully executable jar file for our Grails application we must add the following lines to our build.gradle file:

// File: build.gradle
...
// Disable war plugin to create a jar file
// otherwise a fully executable war file
// is created.
//apply plugin: 'war'

...
springBoot {
    // Enable the creation of a fully
    // executable archive file.
    executable = true
}

Next we execute the Gradle assemble task to create the fully executable archive:

grails> assemble
...
:compileGroovyPages
:jar
:bootRepackage
:assemble

BUILD SUCCESSFUL

Total time: 5.619 secs
| Built application to build/libs using environment: production
grails>

We can find the executable archive file in the build/libs directory. Suppose our Grails application is called grails-full-executable-jar and has version 0.1 - we can execute the jar file grails-full-executable-jar-0.1.jar:

$ cd build/libs
$ ./grails-full-executable-jar-0.1.jar
Grails application running at http://localhost:8080 in environment: production

The launch script that is prepended to the archive file can be changed by defining a new launch script with the springBoot property embeddedLaunchScript. The default launch script that is used has some variable placeholders we can change using the embeddedLaunchScriptProperties property. For example, the launch script can determine if the script is used to run the application standalone or as a Linux/Unix service, and it will act accordingly. We can also set the mode property to service so it will always act like a Linux/Unix service. Furthermore, we can set some meta information for the launch script with several properties. To learn more about the different options see the Spring Boot documentation.

// File: build.gradle
...
springBoot {
    // Enable the creation of a fully
    // executable archive file.
    executable = true

    // Set values for variable placeholders
    // in the default launch script.
    embeddedLaunchScriptProperties =
        [initInfoDescription: project.description,
         initInfoShortDescription: project.name,
         initInfoProvides: jar.baseName,
         mode: 'service']
}

After we have recreated the archive file we can check the launch script that is created:

$ head -n 55 build/libs/grails-full-executable-jar-0.1.jar
#!/bin/bash
#
#    .   ____          _            __ _ _
#   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
#  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
#   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
#    '  |____| .__|_| |_|_| |_\__, | / / / /
#   =========|_|==============|___/=/_/_/_/
#   :: Spring Boot Startup Script ::
#

### BEGIN INIT INFO
# Provides:          grails-full-executable-jar
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: grails-full-executable-jar
# Description:       Sample Grails Application
# chkconfig:         2345 99 01
### END INIT INFO

[[ -n "$DEBUG" ]] && set -x

# Initialize variables that cannot be provided by a .conf file
WORKING_DIR="$(pwd)"
# shellcheck disable=SC2153
[[ -n "$JARFILE" ]] && jarfile="$JARFILE"
[[ -n "$APP_NAME" ]] && identity="$APP_NAME"

# Follow symlinks to find the real jar and detect init.d script
cd "$(dirname "$0")" || exit 1
[[ -z "$jarfile" ]] && jarfile=$(pwd)/$(basename "$0")
while [[ -L "$jarfile" ]]; do
[[ "$jarfile" =~ init\.d ]] && init_script=$(basename "$jarfile")
jarfile=$(readlink "$jarfile")
cd "$(dirname "$jarfile")" || exit 1
jarfile=$(pwd)/$(basename "$jarfile")
done
jarfolder="$(dirname "$jarfile")"
cd "$WORKING_DIR" || exit 1

# Source any config file
configfile="$(basename "${jarfile%.*}.conf")"
# shellcheck source=/dev/null
[[ -r "${jarfolder}/${configfile}" ]] && source "${jarfolder}/${configfile}"

# Initialize PID/LOG locations if they weren't provided by the config file
[[ -z "$PID_FOLDER" ]] && PID_FOLDER="/var/run"
[[ -z "$LOG_FOLDER" ]] && LOG_FOLDER="/var/log"
! [[ -x "$PID_FOLDER" ]] && PID_FOLDER="/tmp"
! [[ -x "$LOG_FOLDER" ]] && LOG_FOLDER="/tmp"

# Set up defaults
[[ -z "$MODE" ]] && MODE="service" # modes are "auto", "service" or "run"
$ cd build/libs
$ ./grails-full-executable-jar.0.1.jar
Usage: ./grails-full-executable-jar-0.1.jar {start|stop|restart|force-reload|status|run}
$

Written with Grails 3.1.8.

Grail (web browser) JAR (file format) Executable Archive file application

Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Use AzureSignTool to Sign Executables With Azure DevOps
  • Build a Java Backend That Connects With Salesforce
  • Build Even Faster Quarkus Applications With fast-jar
  • Deploy Spring Boot Apps From Jar to War

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: