Embedded Jetty server example

Before I worked for sky I used to package my web services in a .war file and deploy them in a running server like Tomcat or Glassfish. When I started working at Sky I found out that they run apps using embedded servers. It can really speed up the time to run app, which is great for things like running acceptance tests. In this post I am going to make an example of how to write an app with an embedded Jetty container.

All the code can be found in https://github.com/obprado/EmbeddedJetty, but I will reference every commit on each section.

Simplest possible Jetty Server

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.3.8.v20160314</version>
    </dependency>

public class EntryPoint {

    public static void main(String[] args) throws Exception {
        int port = 8080;
        Server server = new Server(port);
        server.start();
    }
}

As you probably have guessed, this will start a new server in the 8080 port. It is a very dumb server, it only returns a 404 page to anything. You can test it accessing http://localhost:8080/.

In some what ‘server.join()’ does. Keep in mind that ‘server.start()’ creates several threads. That means that not everything that is triggered by the start method is synchronous. There is a chance that whatever is executed after start() will happen before the server starts completely. The join() method will block the caller until all the server has started up.

Repo: https://github.com/obprado/EmbeddedJetty/tree/c87353121acc4d18b411059194b212bb2b8d1c1e

Adding a handler

Lets get our server to actually do a hello world.

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by Omar on 20/07/16.
 */
public class EntryPoint {

    public static void main(String[] args) throws Exception {
        int port = 8080;
        Server server = new Server(port);
        server.setHandler(new HelloJettyHandler());
        server.start();
        server.join();
    }

    private static class HelloJettyHandler extends AbstractHandler {
        public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
            request.setHandled(true);
            httpServletResponse.getWriter().write(&amp;amp;quot;Hello embedded jetty!!!&amp;amp;quot;);
        }
    }
}

Now our server will answer with a fixed message to every request.

Repo: https://github.com/obprado/EmbeddedJetty/tree/a2e172fc5cdc26474c579af2eb8420192678e99c

Adding a second connector

What happens if for some reason we want our server to be able to respond to requests on two port? For example, we could have a port where we listen to http requests and another port for https requests. So far, we only have one  connector so any configuration change (port, maximum idle time, number of threads) will affect to all the requests that we process. If we want to partition our system and have different configuration sets living together, we will need connectors.

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by Omar on 20/07/16.
 */
public class EntryPoint {

    public static void main(String[] args) throws Exception {
        int defaultPort = 8080;
        int adminPort = 9999;
        Server server = new Server();
        server.addConnector(serverConnector(defaultPort, server));
        server.addConnector(serverConnector(adminPort, server));
        server.setHandler(new HelloJettyHandler());
        server.start();
        server.join();
    }

    private static ServerConnector serverConnector(int port, Server server) {
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(port);
        return connector;
    }

    private static class HelloJettyHandler extends AbstractHandler {
        public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
            request.setHandled(true);
            httpServletResponse.getWriter().write(&amp;amp;quot;Hello embedded jetty!!!&amp;amp;quot;);
        }
    }
}

Now the server will respond in both 8080 and 9999 ports.

Repo: https://github.com/obprado/EmbeddedJetty/tree/bef9f58f217e4c8eea9bc92ca3735962443ed797

Servlets

Ok, so our server is running but… What is you want to use servlets? In the examples so far the logic for processing the requests was in a Jetty Handler. Handlers give you a lot of flexibility but most of the time you will want to use a Java Servlet or something that runs on top of it.

...
    <properties>
        <jetty.version>9.3.8.v20160314</jetty.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jetty.version}</version>
        </dependency>
    </dependencies>
...

...
   public static void main(String[] args) throws Exception {
        int defaultPort = 8080;
        int adminPort = 9999;
        Server server = new Server();
        server.addConnector(serverConnector(defaultPort, server));
        server.addConnector(serverConnector(adminPort, server));
        server.setHandler(helloServletHandler());
        server.start();
        server.join();
    }

    private static ServletContextHandler helloServletHandler() {
        ServletContextHandler servletHandler = new ServletContextHandler();
        servletHandler.addServlet(new ServletHolder(new HelloWorldHttpServlet()), &amp;amp;quot;/hello&amp;amp;quot;);
        return servletHandler;
    }

    private static class HelloWorldHttpServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().write("Hello from a servlet!!!!");
        }

    }
...

Now if you run your server and  open http://localhost:8080/hello or http://localhost:9999/hello you will see the text answer.

Repo: https://github.com/obprado/EmbeddedJetty/tree/0c17de59297a0e3cf6bfb4086643c2a6b64d0e97

On my next post I will write an acceptance test using Yatspec and we will see how having an embedded server can be handy to run tests that require our hole server to be up, specially if we want them to run fast.

Header image: https://pixabay.com/en/jetty-boardwalk-sunset-lake-pier-1030712/

Header image license: https://pixabay.com/en/service/terms/#usage

Advertisements

One Comment Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s