How-to Install Jetty 9 On Ubuntu 14.04

Want your very own server? Get our 1GB memory, Xeon V4, 25GB SSD VPS for £10.00 / month. Get a Cloud Server

Overview

Ubuntu 14.04 (Trusty Tahr) shipped with Jetty 8. You might want to use the latest version of Jetty which is Jetty 9.

Jetty 9 already shipped in Ubuntu 16.04 (Xenial Xerus) but you might still need to use Ubuntu 14.04 on your environment but at the same time you want to use.

Jetty 9 Features

Jetty 9 initial stable version was relased on 2012. Several main features that it shipped with :

Supports next generation protocol like SPDY, WebSockets, MUX and HTTP/2 are supported equals to HTTP/1.1

Content push both in client and server

Improved WebSocket Server and Client

Java 7 support that take advantage of improved APIs in the JVM regarding concurrrency and nio.

Ready for Servlet 3.1

Asynchronous HTTP Client

Pluggable Modules

Improved SSL support

Lightweight in size that enable Jetty to serve tens's of thousands of connection with very small memory footprints.

Embeddable in our application so we can just run our application as standalone application.

Jetty 9.3 Features

HTTP2 support

Application Layer Protocol Negotiation

Server Name Indication (SNI) support for TLS/SSL negotiation. This enables jetty to use certificates with one main domain add multiple Subject Alternate Name.

Targeted for Java 8. This change is due to the SNI extension on Java 8 API and HTTP specification need for TLS ciphers that are only available in Java 8.

In this tutorial we'll learn how-to install and configure Jetty 9 on Ubuntu 14.04.

Prerequisites

This tutorial assumes that we have clean install of Ubuntu Server 14.04. We will update the OS to the latest version before installing the Jetty 9 prerequisites and Jetty 9 itself.

Update Base OS

The first step that we need to do is updating the system to latest update. We can do that using command below:

$ sudo apt-get update $ sudo apt-get upgrade

Install Oracle JDK 8

Now, let's install Java Development Kit 8. We will use Oracle JDK instead of OpenJDK version of JDK 8.

Add the webupd8team ppa repository :

$ sudo add-apt-repository ppa:webupd8team/java ... Press [ENTER] to continue or ctrl-c to cancel adding it gpg: keyring `/tmp/tmpfkhyecrx/secring.gpg' created gpg: keyring `/tmp/tmpfkhyecrx/pubring.gpg' created gpg: requesting key EEA14886 from hkp server keyserver.ubuntu.com gpg: /tmp/tmpfkhyecrx/trustdb.gpg: trustdb created gpg: key EEA14886: public key "Launchpad VLC" imported gpg: no ultimately trusted keys found gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) OK

We need to press enter to continue adding the webupd8team PPA repository. The output above is truncated to show only the important part.

Let's apt-get download and read metadata of the new repository that we just added:

$ sudo apt-get update

Install JDK 8.

$ sudo apt-get -y install oracle-java8-installer

the -y option above will make you agree automatically with packages to be installed including dependencies. If you want to check what packages will be installed you can remove the -y option above.

Package configuration. Choose OK

HP_NO_IMG/data/uploads/users/06ec5e3c-c6e5-4649-b1e7-35579de65459/1815272966.png" alt="" /> Accepting Oracle Binary Code Lisence Terms. Choose Yes

HP_NO_IMG/data/uploads/users/06ec5e3c-c6e5-4649-b1e7-35579de65459/10630431.png" alt="" />

After installing Java 8, you can check the current java version by running command below :

$ java -version java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

We confirmed that we already have JDK 8 installed.

Install Jetty 9

In this tutorial we will install Jetty 9.3, we can get the latest version of jetty from the Jetty download page

Download Jetty 9.3.12 package:

$ wget -c http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.12.v20160915/jetty-distribution-9.3.12.v20160915.tar.gz

Extract the Jetty package:

$ tar xzf jetty-distribution-9.3.12.v20160915.tar.gz

Rename the directory to jetty and move it to /opt :

$ mv jetty-distribution-9.3.12.v20160915 jetty9 $ sudo mv jetty9 /opt

We will create a user and group named jetty that will be used to run Jetty. Create the group first:

$ sudo addgroup --quiet --system jetty

Create the jetty system user.

$ sudo adduser --quiet --system --ingroup jetty --no-create-home --disabled-password jetty

Modify the /etc/passwd entry to change home and group for jetty user.

$ sudo usermod -c "Jetty 9" -d /opt/jetty9 -g jetty jetty

Change ownership of /opt/jetty9 directory to user jetty and group jetty .

$ sudo chown -R jetty:jetty /opt/jetty9

Change the permission of /opt/jetty9 directory.

$ sudo chmod u=rwx,g=rxs,o= /opt/jetty9

Configure Jetty 9

Create logs directory

We need to create directory for Jetty 9 to store logs:

$ sudo mkdir /var/log/jetty9

And change the ownership of the newly created directory to user jetty and group jetty :

$ sudo chown -R jetty:jetty /var/log/jetty

Create a Default Configuration File for Jetty

We will create a default configuration file for jetty. This file will be read by jetty init script and also the crontab script. Create a new file /etc/default/jetty9 with content below:

# change to 1 to prevent Jetty from starting NO_START=0 # change to 'no' or uncomment to use the default setting in /etc/default/rcS VERBOSE=yes # Run Jetty as this user ID (default: jetty) # Set this to an empty string to prevent Jetty from starting automatically JETTY_USER=jetty # The home directory of the Java Runtime Environment (JRE). You need at least # Java 6. If JAVA_HOME is not set, some common directories for OpenJDK and # the Oracle JDK are tried. #JAVA_HOME= # Extra options to pass to the JVM #JAVA_OPTIONS="-Xmx256m -Djava.awt.headless=true" # Timeout in seconds for the shutdown of all webapps #JETTY_SHUTDOWN=30 # Additional arguments to pass to Jetty #JETTY_ARGS= # Jetty uses a directory to store temporary files like unpacked webapps #JETTY_TMP=/var/cache/jetty9 JETTY_HOME=/opt/jetty9 JETTY_LOGS=/var/log/jetty9 # Default for number of days to keep old log files in /var/log/jetty9/ #LOGFILE_DAYS=14 # If you run Jetty on port numbers that are all higher than 1023, then you # do not need authbind. It is used for binding Jetty to lower port numbers. # (yes/no, default: no) #AUTHBIND=yes

Log Files Cron

Now, let's create the crontab configuration file that will rotate log jetty9 log files. Create a new file on /etc/cron.daily/jetty9 with content below:

#!/bin/sh NAME=jetty9 DEFAULT=/etc/default/$NAME # The following variables can be overwritten in $DEFAULT # Default for number of days to keep old log files in /var/log/jetty/ LOGFILE_DAYS=14 # End of variables that can be overwritten in $DEFAULT # overwrite settings from default file if [ -f "$DEFAULT" ]; then . "$DEFAULT" fi if [ -d /var/log/$NAME ]; then find /var/log/$NAME/ -name *.log -mtime +$LOGFILE_DAYS -print0 | xargs --no-run-if-empty -0 rm -- fi

Create an Init Script to Manage Jetty9 Service

The Jetty package comes with an init script. It's located in the bin directory with the name jetty.sh. We will create the init script to manage Jetty 9 service by creating symlink to that file.

$ sudo ln -sf /opt/jetty9/bin/jetty.sh /etc/init.d/jetty9

Make Jetty 9 Start on Boot

We'll make sure Jetty 9 running automatically on boot using update-rc.d .

$ sudo update-rc.d jetty9 defaults update-rc.d: warning: /etc/init.d/jetty9 missing LSB information update-rc.d: see Adding system startup for /etc/init.d/jetty9 ... /etc/rc0.d/K20jetty9 -> ../init.d/jetty9 /etc/rc1.d/K20jetty9 -> ../init.d/jetty9 /etc/rc6.d/K20jetty9 -> ../init.d/jetty9 /etc/rc2.d/S20jetty9 -> ../init.d/jetty9 /etc/rc3.d/S20jetty9 -> ../init.d/jetty9 /etc/rc4.d/S20jetty9 -> ../init.d/jetty9 /etc/rc5.d/S20jetty9 -> ../init.d/jetty9

Managing the Jetty 9 Service

Now Jetty 9 is ready. Let's check jetty 9's service status:

$ sudo service jetty9 status Jetty NOT running START_INI = /opt/jetty9/start.ini START_D = /opt/jetty9/start.d JETTY_HOME = /opt/jetty9 JETTY_BASE = /opt/jetty9 JETTY_CONF = /opt/jetty9/etc/jetty.conf JETTY_PID = /var/run/jetty9.pid JETTY_START = /opt/jetty9/start.jar JETTY_LOGS = /opt/jetty9/logs JETTY_STATE = /opt/jetty9/jetty9.state CLASSPATH = JAVA = /usr/bin/java JAVA_OPTIONS = -Djetty.logging.dir=/opt/jetty9/logs -Djetty.home=/opt/jetty9 -Djetty.base=/opt/jetty9 -Djava.io.tmpdir=/tmp JETTY_ARGS = jetty.state=/opt/jetty9/jetty9.state jetty-logging.xml jetty-started.xml RUN_CMD = /usr/bin/java -Djetty.logging.dir=/opt/jetty9/logs -Djetty.home=/opt/jetty9 -Djetty.base=/opt/jetty9 -Djava.io.tmpdir=/tmp -jar /opt/jetty9/start.jar jetty.state=/opt/jetty9/jetty9.state jetty-logging.xml jetty-started.xml

The output above showed that the Jetty 9 process is not running, let's start Jetty 9 using command below:

$ sudo service jetty9 start Starting Jetty: OK Tue Oct 25 23:56:08 UTC 2016

When we check Jetty 9's status after starting it shows that Jetty is running. It also show the pid of Jetty 9

$ sudo service jetty9 status Jetty running pid=21768 ...

We can also check whether the Jetty process is running or not using netstat by listing all listening ports on the server.

$ sudo netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1365/sshd tcp6 0 0 :::8080 :::* LISTEN 21768/java tcp6 0 0 :::22 :::* LISTEN 1365/sshd

The output above shows that there is a java process that is listening on port 8080 , this is Jetty's default port.

Now point your browser to http://:8080

HP_NO_IMG/data/uploads/users/06ec5e3c-c6e5-4649-b1e7-35579de65459/480901193.png" alt="" />

Deploying Applications

Deploying applications on Jetty 9 is easy. We only have to copy the .war file to webapps directory. This directory is scanned by Jetty and it will run the files available in that directory.

The sample applications is located at /opt/jetty9/demo-base/webapps/ . We will copy async-rest sample to the webapps directory.

sudo cp /opt/jetty9/demo-base/webapps/async-rest.war /opt/jetty9/webapps/

The Jetty log files are rotated daily. The log file name format is YYYY_MM_DD.stderrout.log and is located at /var/log/jetty9 . After copying the sample we will see similar output like below that show the async-rest sample is deployed.

2016-11-01 20:51:26.554:WARN::Scanner-0: async-rest webapp is deployed. DO NOT USE IN PRODUCTION! 2016-11-01 20:51:26.730:INFO:oejsh.ContextHandler:Scanner-0: Started o.e.j.w.WebAppContext@5bd204cd{/async-rest,[file:///tmp/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-4799009764757275722.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-4799009764757275722.dir/webapp/WEB-INF/lib/example-async-rest-jar-9.3.12.v20160915.jar!/META-INF/resources],AVAILABLE}{/async-rest.war}

When we open Jetty it will show that there is one application deployed. We can click on the link. The app also available on http://server-address:8080/async-rest , so the file name will be directory name on the url

HP_NO_IMG/data/uploads/users/06ec5e3c-c6e5-4649-b1e7-35579de65459/397508108.png" alt="" />

When we click the application the async-rest sample will be shown.

HP_NO_IMG/data/uploads/users/06ec5e3c-c6e5-4649-b1e7-35579de65459/1280541191.png" alt="" />

Removing Applications

Removing applications is also easy, we just have to remove the .war file from webapps directory. Let's remove the sample async-rest.war that we just deploy.

$ sudo rm -f /opt/jetty9/webapps/async-rest.war

On the log file we will see that the application is stopped by Jetty:

2016-11-01 20:49:35.640:INFO:oejsh.ContextHandler:Scanner-0: Stopped o.e.j.w.WebAppContext@3c9d0b9d{/async-rest,null,UNAVAILABLE}{/async-rest.war}

Using Nginx as a Reverse Proxy for Jetty 9

We will install Nginx and use it as reverse proxy for Jetty 9. In this setup we will forward requests that come to Nginx to Jetty 9 on the same machine but we can also use Nginx to forward request to another machines and load balance the request.

We will also use Nginx to serve site on https mode so the SSL connection from client to server will be handled by Nginx.

Install Nginx

We will install Nginx from nginx.org repository instead of from ubuntu repository. The reason is that the nginx.org repository provides a newer version of nginx so we can get the latest and also secure version of Nginx.

First of all let's add Nginx.org package signing key. We have to add this key so apt can verify that the packages that we download from nginx repository is not tampered on the way to our server.

$ wget -c -O- http://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Add nginx.org Repository:

$ echo "deb http://nginx.org/packages/ubuntu/ trusty nginx" | sudo tee -a /etc/apt/sources.list.d/nginx.list > /dev/null

Update apt metadata so that it know the contents of Nginx.org repository and install Nginx.

$ sudo apt-get update $ sudo apt-get -y install nginx

Now we have nginx installed, we can check it by checking the status of the service :

$ sudo service nginx status

Configure Nginx Sites For Jetty 9 Nexus

In this section we'll learn how to configure Nginx to serve as http only proxy and https only proxy.

The configuration directory structure created by nginx package from nginx.org repository is a little bit different with configuration of Nginx package from Ubuntu repository.

We will reconfigure Nginx configuration directory to make it easier to enable and disable site configuration.

Create two new directories named sites-available and sites-enabled with commands below:

$ sudo mkdir /etc/nginx/sites-available $ sudo mkdir /etc/nginx/sites-enabled

open /etc/nginx/nginx.conf find line:

include /etc/nginx/conf.d/*.conf;

replace with:

include /etc/nginx/sites-enabled/*.conf;

Remove contents of /etc/nginx/conf.d

$ sudo rm -f /etc/nginx/conf.d/*

Now we are ready to configure Jetty 9 site.

HTTP Only Configuration

Create the file /etc/nginx/sites-available/jetty-http.conf with the contents below. You need to change the server_name line below with the domain name that you plan to use for Jetty 9.

server { listen 80 default_server; listen [::]:80 default_server; server_name jetty9.exampleserver.xyz; root /usr/share/nginx/jetty9; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; location / { proxy_pass http://localhost:8080; } }

Enable configuration by creating asymbolic link:

$ sudo ln -sf /etc/nginx/sites-available/jetty-http.conf /etc/nginx/sites-enabled/jetty-http.conf

Now reload Nginx:

$ sudo service nginx reload

Nginx is ready to work as reverse proxy. You can now open http://<server address/ . This time without Jetty port ( 8080 ) since Nginx already listen on port 80 and forward the request to Jetty.

HTTPS Only Configuration

If you already follow the configuration above you can skip this section, but if you want to serve jetty only via https you can follow this section.

The configuration below will make Nginx serve both on http port and https port. When a request comes to http port it will be redirected to https port.

We assume that you already have an ssl certificate and the private key pair. When using this configuration you need to change server_name , ssl_certificate and ssl_certificate_key lines below.

Before creating the configuration file. Let's create a new folder to put ssl certificate.

$ sudo mkdir /etc/nginx/ssl

Create a new configuration file /etc/nginx/sites-available/jetty-ssl.conf with contents below:

server { listen 80 default_server; listen [::]:80 default_server; # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response. return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name jetty9.exampleserver.xyz; root /usr/share/nginx/jetty9; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/nginx/ssl/jetty9.exampleserver.xyz.crt; ssl_certificate_key /etc/nginx/ssl/jetty9.exampleserver.xyz.key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # intermediate configuration. tweak to your needs. ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on; # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; location / { proxy_pass http://localhost:8080; } }

Enable the site by creating symbolic link using command below:

$ sudo ln -sf /etc/nginx/sites-available/jetty-ssl.conf /etc/nginx/sites-enabled/jetty-ssl.conf

If you already follow the http section above you need to disable the site by removing the symbolic link.

$ sudo rm -f /etc/nginx/sites-enabled/jetty-http.conf

Test the Nginx configuration using comand below:

$ sudo service nginx configtest nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

If the output is different to the above, Nginx will show an error message and show which file and line of the configuration is not correct.

Reload Nginx configuration using command below:

$ sudo service nginx reload

Summary

In this tutorial we have learned how to install and configure Jetty 9 on ubuntu 14.04 Trusty Tahr. We also learned how to configure Jetty 9 and also using Nginx as reverse proxy for Jetty 9.