How to start and stop Jetty – revisited

I mentioned in my previous post that I would blog about some of the things I learnt while putting together the Seam / JSF versus Wicket “perfbench“.

A while back I posted about how to start and stop Jetty from Ant – useful for those using the Jetty downloaded distribution. In this post I show how to cleanly shutdown a Jetty instance started in “embedded” mode. This tip may be useful for those using Jetty in a continuous integration build – for e.g. when Selenium tests are involved.

Info on starting an embedded Jetty instance is out there but I was not able to find ways to cleanly shutdown – other than hacks like this.

Update 2009-04-07: just found a blog post by Stephen Haberman that has a detailed explanation of WAR-less Development with Jetty

Here’s the code to start Jetty. The trick is to spawn a thread with a socket listening on another port (8079 in this case) that we can connect to later:

package mypackage;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

public class Start {

    private static Server server;

	public static void main(String[] args) throws Exception {
		server = new Server();
		SocketConnector connector = new SocketConnector();
		connector.setPort(8080);
		server.setConnectors(new Connector[] { connector });
		WebAppContext context = new WebAppContext();
		context.setServer(server);
		context.setContextPath("/wicket-jpa");
		context.setWar("src/main/webapp");
		server.addHandler(context);
        Thread monitor = new MonitorThread();
        monitor.start();
        server.start();
        server.join();
	}

    private static class MonitorThread extends Thread {

        private ServerSocket socket;

        public MonitorThread() {
            setDaemon(true);
            setName("StopMonitor");
            try {
                socket = new ServerSocket(8079, 1, InetAddress.getByName("127.0.0.1"));
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void run() {
            System.out.println("*** running jetty 'stop' thread");
            Socket accept;
            try {
                accept = socket.accept();
                BufferedReader reader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
                reader.readLine();
                System.out.println("*** stopping jetty embedded server");
                server.stop();
                accept.close();
                socket.close();
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

}

The “MonitorThread” in the inner class above stops the embedded Jetty server if a line feed is received. So the code to stop Jetty is pretty simple. Here we duly send “\r\n” to port 8079:

package mypackage;

import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Stop {

    public static void main(String[] args) throws Exception {
        Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8079);
        OutputStream out = s.getOutputStream();
        System.out.println("*** sending jetty stop request");
        out.write(("\r\n").getBytes());
        out.flush();
        s.close();
    }
    
}

So how does one use this from Ant? Easy !

<target name="jetty-cycle">               
    <parallel>
        <java classname="mypackage.Start" classpathref="test.classpath" fork="true"/>
        <sequential>
            <waitfor>
                <socket server="127.0.0.1" port="8080"/>
            </waitfor>                
            <antcall target="my-tests"/>                            
            <java classname="mypackage.Stop" classpathref="test.classpath"/>                 
        </sequential>
    </parallel>
</target> 

Full disclosure: I adapted the approach from the Jetty code you can find over here ;)

About Peter Thomas
https://twitter.com/ptrthomas

18 Responses to How to start and stop Jetty – revisited

  1. whitelassiblog says:

    a very nice and informative blog indeed !

    congrats.

  2. vatsan says:

    Super useful, thanks!

  3. Shihab says:

    COuld you please tell me how can we load 3d view of images from set of images. Like I have many image slices. I would like to view those images in a 3D view. Could you please tell me this?

  4. Peter Thomas says:

    @Shihab huh!? why me ?

  5. orange80a says:

    What does refer to?

    Thanks!

  6. Pingback: Why you should use the Maven Ant Tasks instead of Maven or Ivy « Incremental Operations

  7. djohn says:

    Can we use the above code for SSL connection also, if not then how?

  8. szyszy says:

    Probably a beginner question, but..
    Why Jetty can only be stopped by another monitor thread?

  9. Thanks!

    That helped me a lot!!!

  10. Taner Diler says:

    helpfully article. I’m deploying a war file to embedded jetty. It works when I call server.start(). But When I explore a service, jetty gives me ClassNotFoundException. I think the embedded server doesn’t load classes (located /WEB-INF/classes) in war. How can I specify the classes location to class loader?

  11. Pingback: Embedding Jetty with Netbeans 7 (and Maven) | Giant Flying Saucer

  12. mariomanumanu says:

    Thanks!

    Very useful article.

  13. Noah DeMarco says:

    All you need to do is put a “System.in.read(); server.stop();” in between the start() and the join(). This will stop the server after a line feed is entered in the console.

  14. davotoula says:

    I was looking for a clean solution to shut down embedded jetty and this helped.

    I’m a bit surprised that that org.eclipse.jetty.server.Server doesn’t do this for you.

    Out of interest, do you know how the jetty-maven-plugin implements stop port and stop command?

    thanks!

    dk

  15. Peter Thomas says:

    All you need to do is put a “System.in.read(); server.stop();” in between the start() and the join(). This will stop the server after a line feed is entered in the console.

    Of course, and that is how the maven jetty:run plugin is implemented. But as mentioned in the post, this approach is useful for those running a hands-free build for e.g. Selenium tests + continuous integration.

  16. Christian says:

    That’s very helpful, thanks.
    But I believe there must be solution without opening another port on the system. Is it still the way to implement a server shutdown in the actual version?

  17. Pingback: Automatiser ses tests fonctionnels avec Ant | Blog Xebia France

  18. fucking genius, thanks a lot.

Leave a comment

  • Design a site like this with WordPress.com
    Get started