7

I have an application runs on an embedded jetty server. Now i want to start/stop the server as a service. I use a script to start the server.

java $JAVA_OPTS -DREQ_JAVA_VERSION=$JAVA_VERSION -jar myjetty.jar

Main Class

Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(PORT);
server.addConnector(connector);
HandlerCollection handlers = new HandlerCollection();
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(home + "/logs/access_" + logFileDateFormat
            + ".log");
requestLog.setFilenameDateFormat(logFileDateFormat);
requestLog.setRetainDays(10);
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogCookies(false);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
server.setHandler(handlers);
server.start();
server.join();

This starts the server.Stopping and/or Restarting an embedded Jetty instance via web call can be used to stop server but, How to stop the server from the script? and what changes should i make to shout down server in the main class.

jos
  • 1,082
  • 5
  • 19
  • 45
  • When do you want to shut down the server? – SpaceTrucker May 20 '15 at 11:03
  • You are looking for `server.stop()`? How and when you will trigger the shutdown? – SubOptimal May 20 '15 at 11:05
  • 1
    like a service `sudo service myjetty start` to start the server and `sudo service myjetty stop` basically server.stop() is what i shoud do.But how can i invoke that ? – jos May 20 '15 at 11:16
  • 1
    @SubOptimal i should stop jetty as shutdown.sh do in tomcat – jos May 20 '15 at 11:19
  • 2
    Why you can't use the solution from your posted link `curl -v http://localhost:9103/stop`? – SubOptimal May 20 '15 at 12:42
  • That is an option. I am looking for another option like `java -jar myjetty.jar stop` by passing the stop argument it can be stoped – jos May 20 '15 at 13:05

4 Answers4

9

Since Jetty 7.5.x you can use org.eclipse.jetty.server.handler.ShutdownHandler in your code:

Server server = new Server(8080);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]
{ someOtherHandler, new ShutdownHandler("secret_password", false, true) });
server.setHandler(handlers);
server.start();

... which will allow you to shut down your jetty by issuing the following http POST request:

curl -X POST http://localhost:8080/shutdown?token=secret_password
diginoise
  • 7,352
  • 2
  • 31
  • 39
  • 1
    @jos if you like it, put a ring on it ;) – diginoise Oct 04 '17 at 15:46
  • 2
    This is the best answer in my opinion. I'd only suggest to put the ShutdownHandler as the first one the handlers list so that it's the first to be taken into account in the chain. For example if you have a ServletHandler configured first, this can prevent the Shutdown to be reached. – Lorenzo Conserva Sep 30 '20 at 13:52
  • 1
    Just to close the loop on Lorenzo's comment above, line 4 of the solution becomes: { new ShutdownHandler("secret_password", false, true), someOtherHandler }); – beaudet Jan 24 '22 at 23:27
  • @beaudet feel free to edit the answer and I will happily approve. – diginoise Jan 25 '22 at 14:55
  • I just tried the code above (only one handler) with Jetty 10.0.9, but I'm not getting any response from the ShutdownHandler, I mean, the getResponseCode method just keeps waiting and never responds. The handler seems to be there because if I omit its declaration the getResponseMessage returns NotFound. I tried also by curl -X POST http://localhost:8080/shutdown?token=secret and postman and even using a wrong password with the same result. Any clue or idea? Thanks in advance! – Hugo Hernandez Aug 09 '22 at 00:05
  • 1
    hi @HugoHernandez could you try debugging the shutdown procedure and see where it hangs? When you try making the shutdown request in postman, does the request eventually time out after 1min? – diginoise Aug 16 '22 at 14:31
  • Hi @diginoise, thanks for the reply! I set breakpoints inside Server and ShutdownHandler but they were never reached when I sent the request from Postman and it never throws a timeout. But thanks to your suggestion I just realize that if I set the sentShutdownAtStart argument in ShutdownHandler equals true then the server connector is not started, that's why the shutdown requests were not attended by the server. I don't know if it is a bug but it is really annoying to not receive any error or warning by using such a trivial thing as a constructor argument. – Hugo Hernandez Aug 17 '22 at 16:42
5

You can call setStopTimeout(long timeout) to shutdown Jetty in a relatively graceful way. A statisticsHandler must be configured when calling this method.

Referencing: Jetty Server.class setStopTimeout(long)

e.g.

YourServletHandler servletHandler = new YourServletHandler();
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(servletHandler);

Server server = new Server(80);
server.setHandler(statsHandler);
server.setStopTimeout(3000L);

//...
server.start();

//...
server.stop();
bjrara
  • 143
  • 1
  • 2
  • 9
2

There is no predefined solution to shut-down the Jetty server. The only ordered way to shut-down the Jetty server is to call the method stop() on the running server instance. You must implement the way how this method is called yourself.

You could achieve this (for example) by...

  • implementing an RMI server thread and invoke the method from a RMI client
  • implementing a JMX MBean and from a client call a method on that MBean
  • implementing a custom handler like described in the link you have posted

If you only want to find a way which does not depend on additional tools like curl, than you could solve it for example like below (it's your own code with small modifications)

public class MyJetty {

    public static void main(String[] args) throws Exception {
        int PORT = 9103;
        String home = System.getProperty("user.home");
        String logFileDateFormat = "yyyy_MM_dd";

        // execute a request to http://localhost:9103/stop
        // instead of `curl -v http://localhost:9103/stop`
        if (args.length == 1 && "stop".equalsIgnoreCase(args[0])) {
            URL url = new URL("http", "localhost", PORT, "/stop");
            try (InputStream in = url.openStream()) {
                int r;
                while ((r = in.read()) != -1) {
                    System.out.write(r);
                }
                return;
            } catch (IOException ex) {
                System.err.println("stop Jetty failed: " + ex.getMessage());
            }
        }

        Server server = new Server();
        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setPort(PORT);
        server.addConnector(connector);
        HandlerCollection handlers = new HandlerCollection();
        NCSARequestLog requestLog = new NCSARequestLog();
        requestLog.setFilename(home + "/logs/access_" + logFileDateFormat + ".log");
        requestLog.setFilenameDateFormat(logFileDateFormat);
        requestLog.setRetainDays(10);
        requestLog.setAppend(true);
        requestLog.setExtended(false);
        requestLog.setLogCookies(false);
        requestLog.setLogTimeZone(TimeZone.getDefault().getID());
        RequestLogHandler requestLogHandler = new RequestLogHandler();
        requestLogHandler.setRequestLog(requestLog);
        handlers.addHandler(requestLogHandler);

        // the class YourHandler is the one from your link
        handlers.addHandler(new YourHandler(server));

        server.setHandler(handlers);
        server.start();
        server.join();
    }
}
  • start the server with java MyJetty
  • stop the server with java MyJetty stop
SubOptimal
  • 22,518
  • 3
  • 53
  • 69
  • check the stop method in jetty main class. https://github.com/eclipse/jetty.project/blob/master/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java#L472 . – jos May 21 '15 at 13:58
0

I don't know why (or if it is a bug) but in my case I had to set shutdownAtStart argument to false to get it working. If I set it as true the Server connector never starts, so it doesn't attend external requests like http://localhost:8888/shutdown?token=secret

new ShutdownHandler("secret", false, false);
Hugo Hernandez
  • 123
  • 1
  • 11