animesh kumar

Running water never grows stale. Keep flowing!

Posts Tagged ‘Resteasy

Jetty Executable Webserver Archetype

with 2 comments

We create and deploy many rest based API apps on our servers. Now, instead of managing multitudes of webservers on different machines, we make our deployable archives wrapped with all the necessary dependencies in order to be self-executable. Benefits?

  • We just have to ensure that all our servers have the same Java environment, and no other dependencies.
  • No waste of time configuring, managing web (tomcat, jetty etc.) servers.
  • And, we only have to distribute a single executable.

Hassle free management. Won’t you agree?

To cut down on bootstrapping time, we have created a maven archetype to help us quickly create and start on new API projects. Our tech stack is Google Guice, JBoss Resteasy, Logback, and Embedded Jetty.

Github link: https://github.com/anismiles/jetty-webserver-archetype

Install

You can either build/install from source

git clone https://github.com/anismiles/jetty-webserver-archetype.git
mvn clean install

Or you can simply download the jar and install that.

mvn install:install-file \
-Dfile=jetty-webserver-archetype-1.0.jar \
-DgroupId=com.strumsoft \
-DartifactId=jetty-webserver-archetype \
-Dversion=1.0 \
-Dpackaging=jar \
-DgeneratePom=true

Usage

Let’s say you want to create a new project “hello-world” with group “com.hello.world”, you would run:

mvn archetype:generate \
-DgroupId=com.hello.world \
-DartifactId=hello-world \
-Dversion=1.0-SNAPSHOT \
-DarchetypeGroupId=com.strumsoft \
-DarchetypeVersion=1.0 \
-DarchetypeArtifactId=jetty-webserver-archetype

That’s it. You are ready to roll. You have set up a basic working API app. Now, you can run it in dev mode

mvn clean jetty:run

Or in production mode

mvn clean package
java –jar target/hello-world-1.0-SNAPSHOT-dist.war start &

To check, open http://localhost:8085/
To stop:

java –jar target/hello-world-1.0-SNAPSHOT-dist.war stop

Further, you can pass additional Jetty, Logback or your App’s properties

java \
-Djetty.configurationFile=<jetty-config> \
-Dapp.configurationFile=<app.properties> \
-Dlogback.configurationFile=<logback.xml> \
–jar target/hello-world-1.0-SNAPSHOT-dist.war start &

They will override default properties setup by the executable.
Ideally you might want to create an init.d file to start and stop you API app efficiently. Here is a prototype:

#!/bin/sh

# Executable war file
WAR_FILE=/var/apps/<my-war-file>.war

# Configuration files
APP_NAME=<app-name>

JETTY_CONFIG=/etc/${APP_NAME}-jetty.properties
APP_CONFIG=/etc/${APP_NAME}-app.properties
LOGBACK_CONFIG=/etc/${APP_NAME}-logback.properties

# Process
PIDFILE=/var/run/${APP_NAME}.pid

# Java arguments
JAVA_ARGS="-Djetty.configurationFile=${JETTY_CONFIG} -Dapp.configurationFile=${APP_CONFIG} -Dlogback.configurationFile=${LOGBACK_CONFIG}"

# Command
CMD=$1

if [[ -z ${CMD} ]]; then
  java ${JAVA_ARGS} -jar ${WAR_FILE} usage
  exit 1
fi

if [[ ${CMD} == 'start' ]]; then
    if [[ -f ${PIDFILE} ]]; then
        echo "Already running"
        exit 1
    fi

    if [[ -f ${WAR_FILE} ]]; then
        echo "Starting jetty: ${WAR_FILE}"
        java ${JAVA_ARGS} -jar ${WAR_FILE} start &
        PID=$!
        echo "$PID" > ${PIDFILE}
        echo "Started ${APP_NAME} with pid: ${PID}"
    fi

elif [[ ${CMD} == 'stop' ]]; then
    # Try gracefully first
    java ${JAVA_ARGS} -jar ${WAR_FILE} stop
    sleep 10
    if [[ -f ${PIDFILE} ]]; then
        PID=`cat ${PIDFILE}`
        test -z $PID || kill $PID
        rm ${PIDFILE}
        sleep 1
        echo "Forcibly Stopped ${WAR_FILE} with pid: ${PID}"
    fi

else # Just let the other cmds through...
    java ${JAVA_ARGS} -jar ${WAR_FILE} ${CMD}
fi

exit 0

That’s it! have fun. 🙂

Written by Animesh

January 8, 2013 at 1:48 pm