我有一个使用Dropwizard和Gradle开发的项目。当我想启动服务器时,我只需在IntelliJ IDEA中运行它,gradle run
作为运行配置。
这样做启动我的服务器,我可以按预期进行交互,即使使用IntelliJ进行调试也没问题。
但使用"停止"或"重新运行"按钮似乎不会杀死以前启动的服务器。相反,如果我重新运行服务器,我会得到以下异常:
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
所以似乎其他一些程序保留了我想要使用的地址。当我运行ps aux
时,我可以看到我的服务器仍在运行,并且它响应请求。只有当我通过终端杀死它,或者当我退出IntelliJ IDEA时,服务器才会被杀死。
由于这对于开发来说不太好,我在这里寻找一些指导。
答案 0 :(得分:1)
Intellij IDEA had (has?) a bug not being able to terminate gradle tasks.
如果您没有使用gradle 2.1,请尝试升级到2.1。否则,解决方法是添加属性
GRADLE.system.in.process=false
进入文件'bin/idea.properties'
答案 1 :(得分:0)
编辑: 请参阅纳坦的答案以获得真正的解决方案。
如果答案无效,以下是我使用的解决方法: 应用程序类提供了一个特殊的路由,在调用时只会杀死服务器。为了实现这一点,基于答案in the google group,我们在应用程序中设置一个servlet,定义路由然后监听它。
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();
}
}
}