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 Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
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
Partner Zones AWS Cloud
by AWS Developer Relations
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
Partner Zones
AWS Cloud
by AWS Developer Relations
Securing Your Software Supply Chain with JFrog and Azure
Register Today

Trending

  • Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
  • Avoiding Pitfalls With Java Optional: Common Mistakes and How To Fix Them [Video]
  • AI and Cybersecurity Protecting Against Emerging Threats
  • Knowing and Valuing Apache Kafka’s ISR (In-Sync Replicas)

Trending

  • Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
  • Avoiding Pitfalls With Java Optional: Common Mistakes and How To Fix Them [Video]
  • AI and Cybersecurity Protecting Against Emerging Threats
  • Knowing and Valuing Apache Kafka’s ISR (In-Sync Replicas)

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.

Hubert Klein Ikkink user avatar by
Hubert Klein Ikkink
·
Jun. 23, 16 · Tutorial
Like (5)
Save
Tweet
Share
7.91K 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.

Trending

  • Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
  • Avoiding Pitfalls With Java Optional: Common Mistakes and How To Fix Them [Video]
  • AI and Cybersecurity Protecting Against Emerging Threats
  • Knowing and Valuing Apache Kafka’s ISR (In-Sync Replicas)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: