akohout
akohout

Reputation: 1811

IntelliJ IDEA is unable to kill my Dropwizard Server

I have a project that is developed using Dropwizard and Gradle. When I want to start the server, I can simply run it inside IntelliJ IDEA with gradle run as runconfiguration.

Doing so starts my server and I can interact with it as expected, even debugging with IntelliJ is no problem.

But using the "Stop" or "Rerun" buttons don't seem to kill the previously started server. Instead, if I rerun the server I get the following exception:

13:45:48: Executing external task 'run'...
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
Connected to the target VM, address: '127.0.0.1:61376', transport: 'socket'
:run
INFO  [2014-12-16 12:46:01,393] io.dropwizard.server.ServerFactory: Starting my-project
Disconnected from the target VM, address: '127.0.0.1:61376', transport: 'socket'
WARN  [2014-12-16 12:46:01,552] org.eclipse.jetty.util.component.AbstractLifeCycle: FAILED org.eclipse.jetty.server.Server@7a6359b0: java.lang.RuntimeException: java.net.BindException: Address already in use

So it seems like some other program keeps the address I want to use. When I then run ps aux I can see that my server is still running and that it responds to requests. Only if I kill it via terminal, or when I exit IntelliJ IDEA the server gets killed.

As this is not so nice for development I'm searching for some guidance here.

Upvotes: 1

Views: 852

Answers (2)

akohout
akohout

Reputation: 1811

Edit: See Natan's answer for a real solution.

If the answer does not work, here is a workaround I used: The application class provides a special route, which when called simply kills the server. To achieve this, based on the answer in the google group, we set up a servlet in the application, define the route and then listen for it.

public class MyApplication extends Application<MyConfiguration> {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyApplication.class);

    private Server mServer;

    // ...

    @Override
    public void run(final RecommenderConfiguration configuration,
                final Environment environment) throws ClassNotFoundException {
        // ...

        initializeKillCommand(environment);
    }

    private void initializeKillCommand(Environment environment) {
        ServletEnvironment servletEnvironment = environment.servlets();
        servletEnvironment.addServlet(
                "Terminator",
                new ServerTerminator()
        ).addMapping("/kill");

        LifecycleEnvironment lifecycleEnvironment = environment.lifecycle();
        lifecycleEnvironment.addServerLifecycleListener(
            new ServerLifecycleListener() {
                @Override
                public void serverStarted(Server server) {
                    mServer = server;
                }
            }
        );
    }

    private class ServerTerminator extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            LOGGER.info("Received Shutdown Command");

            resp.setContentType("text/html");
            resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
            resp.getWriter().println();

            // Must initiate shut-down in separate thread to not deadlock here
            new Thread() {
                @Override
                public void run() {
                    try {
                        mServer.stop();
                    } catch (Exception ex) {
                        LOGGER.error("Unable to stop the server");
                    }
                }
           }.start();
        }
    }
}

Upvotes: 0

Natan
Natan

Reputation: 2858

Intellij IDEA had (has?) a bug not being able to terminate gradle tasks.

If you aren't using gradle 2.1, try to upgrade to 2.1. Otherwise a workaround is to add the property

GRADLE.system.in.process=false 

into the file 'bin/idea.properties'

Upvotes: 1

Related Questions