Reputation: 1811
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
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
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