How to start and stop Jetty – revisited
January 24, 2009 18 Comments
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 ;)
a very nice and informative blog indeed !
congrats.
Super useful, thanks!
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?
@Shihab huh!? why me ?
What does refer to?
Thanks!
Pingback: Why you should use the Maven Ant Tasks instead of Maven or Ivy « Incremental Operations
Can we use the above code for SSL connection also, if not then how?
Probably a beginner question, but..
Why Jetty can only be stopped by another monitor thread?
Thanks!
That helped me a lot!!!
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?
Pingback: Embedding Jetty with Netbeans 7 (and Maven) | Giant Flying Saucer
Thanks!
Very useful article.
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.
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
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.
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?
Pingback: Automatiser ses tests fonctionnels avec Ant | Blog Xebia France
fucking genius, thanks a lot.