Ninja features a standalone mode where you do not need a separate servlet container. The standalone mode enables you to package your application along with a fast, embedded HTTP server (Jetty in that case). There are several options for packaging your application using standalone mode.
This allows you to drop that self-executing file to your server run your application with zero external dependencies. Due to Ninja's client-side sessions it becomes really simple to have one reverse proxy in front of many Ninja instances.
In order to do so you have to first of all add ninja-standalone as dependency to your pom.xml:
<dependency> <groupId>org.ninjaframework</groupId> <artifactId>ninja-standalone</artifactId> <version>X.X.X</version> </dependency>
Don't forget to change packaging value from war to jar.
<packaging>jar</packaging>
Packaging the application is done via the maven shade plugin. Add the following snipplet to your pom.xml.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.2</version> <configuration> <createDependencyReducedPom>true</createDependencyReducedPom> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>ninja.standalone.NinjaJetty</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
Whenever you build your application on the command line this will generate a fat jar inside your target directory. Usually that file is named roughly MY-APPLICATION-jar-with-dependencies.jar
You can generate the fat jar by calling
mvn clean compile package
Running the fat jar (and your app) is as simple as calling:
java -Dninja.port=9000 -jar MY-APPLICATION-jar-with-dependencies.jar
Incompatibility notice
Please be aware that since Ninja 6.4.3, alongside with Jetty 9.4.12, the dependency allowing Jetty servlets annotations (that should not be
useful for your Ninja Framework project) have been excluded from the stack. This was caused by an incompatibility between the version
of the java bytecode handler ASM
used by this module (6.2) and the java bytecode handler javassist
used by Hibernate.
If you'd like to run your application as a proper daemon on Unix/Mac or as a service on Windows, another option is using the Stork Maven Plugin.
Stork is a collection of utilities for optimizing your “after-build” workflow by filling in the gap between Maven and eventual app execution. In just a couple quick steps, stork will package your Ninja app into a professional .tar.gz file ready for deployment.
Here is an article describing how Ninja apps can be packaged with Stork.
Here is a demo application that integrates with Stork.
Regardless of which option you choose, you can customize your application startup via the following command line parameters:
ninja.port
allows you to select the port on which your
application is starting (8080 by default).ninja.host
allows you to select the host on which your
application will bind (any/0.0.0.0 by default).ninja.idle.timeout
allows you to specify the timeout period after which
idle HTTP connections will be closed. (in msec, 30000 by default)ninja.mode
allows you to select the mode (test, dev, prod)
of your application (prod by default).ninja.external.configuration
allows you to add an external application
configuration (eg -Dninja.external.configuration=conf/production.conf).
Please note that even with an external configuration, if you included a
conf/application.conf
on your classpath (e.g. in your app jar)
then it will be loaded first, followed by the external configuration file.
By using both files, you'll only need to worry about overriding values –
which comes in handy when running in test/production environments.ninja.context
allows you to add a context prefix to your application
(eg -Dninja.context=/your_context_path).ninja.jetty.configuration
allows you to supply a comma-delimited
list of jetty.xml
configuration files to configure the server.
Anything Jetty can do is now available. Please note that if this property is
supplied then the host/port property is skipped and you'll need to configure
that in the jetty.xml
configuration file.
(eg -Dninja.jetty.configuration=jetty.xml,jetty-ssl.xml) Please refer to
Jetty distribution for example config files. For each jetty configuration file
the local filesystem is searched first, followed by the classpath, and if
multiple files are included then each one is applied in order.If you use option #1 and want to register your Ninja standalone application on
your Linux box (Debian, Ubuntu) you can use and adapt the following script. The
script should be copied at /etc/init.d/ninja and can be run via service ninja start
.
#!/bin/bash # chkconfig: 345 20 80 # description: Ninja start/shutdown script # processname: java # # Installation: # copy file to /etc/init.d # chmod +x /etc/init.d/ninja # chkconfig --add /etc/init.d/ninja # chkconfig ninja on # OR on a Debian system # sudo update-rc.d ninja defaults # # Usage: (as root) # service ninja start # service ninja stop # service ninja status # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Path to the application APPLICATION_NAME=my-ninja-service APPLICATION_PATH=/srv/ninja_applications/${APPLICATION_NAME} APPLICATION_JAR=my-ninja-service-1.0-SNAPSHOT-jar-with-dependencies.jar PID_FILE=/var/run/${APPLICATION_NAME}.pid PORT=9013 # Path to the JVM JAVA_BIN=/opt/java-oracle/jdk1.7.0/bin/java PARAMS="-Dninja.port=${PORT} -jar ${APPLICATION_PATH}/${APPLICATION_JAR}" # User running the Ninja process USER=ninja RETVAL=0 start() { if [ -f ${PID_FILE} ]; then echo "Ninja application ${APPLICATION_NAME} already running" else DAEMON_START_LINE="start-stop-daemon --chdir=${APPLICATION_PATH} --make-pidfile --pidfile ${PID_FILE} --chuid ${USER} --exec ${JAVA_BIN} --background --start -- ${PARAMS}" ${DAEMON_START_LINE} RETVAL=$? echo -n "Starting Ninja Application: ${APPLICATION_NAME}... " if [ $RETVAL -eq 0 ]; then echo " - Success" else echo " - Failure" fi echo fi echo } stop() { kill -9 `cat ${PID_FILE}` RETVAL=$? rm -rf ${PID_FILE} echo -n "Stopping Ninja application: ${APPLICATION_NAME}" if [ $RETVAL -eq 0 ]; then echo " - Success" else echo " - Failure" fi echo } status() { if [ -f ${PID_FILE} ]; then echo "Ninja application ${APPLICATION_NAME} running" else echo "Ninja application ${APPLICATION_NAME} not running" fi echo } clean() { rm -f ${PID_FILE} } case "$1" in start) start ;; stop) stop ;; restart|reload) stop sleep 10 start ;; status) status ;; clean) clean ;; *) echo "Usage: $0 {start|stop|restart|status}" esac