IntelliJ IDEA无法杀死我的Dropwizard服务器

时间:2014-12-16 12:54:29

标签: java intellij-idea gradle dropwizard

我有一个使用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时,服务器才会被杀死。

由于这对于开发来说不太好,我在这里寻找一些指导。

2 个答案:

答案 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();
        }
    }
}