2014-12-16 2 views
1

У меня есть проект, который разработан с использованием Dropwizard и Gradle. Когда я хочу запустить сервер, я могу просто запустить его внутри IntelliJ IDEA с gradle run как runconfiguration.IntelliJ IDEA не может убить мой сервер Dropwizard

Выполнение этого запускает мой сервер, и я могу взаимодействовать с ним, как и ожидалось, даже отладка с 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 [email protected]: java.lang.RuntimeException: java.net.BindException: Address already in use 

Так что, похоже, как некоторая другая программа хранит адрес я хочу использовать. Когда я запускаю ps aux, я вижу, что мой сервер все еще работает и что он отвечает на запросы. Только если я убью его через терминал, или когда я выйду из IntelliJ IDEA, сервер будет убит.

Поскольку это не так хорошо для разработки, я ищу здесь некоторые рекомендации.

+0

Фактически, он не убивает исходный экземпляр, поэтому порт все еще связан. У меня была проблема с загрузкой Spring с помощью Gradle в IntelliJ. В конечном итоге я запускаю сервер с помощью стандартной командной строки, и он запускается и прекращается. Не уверен, почему IJ не отпустил это правильно. – cjstehno

+0

В настоящее время я также использую терминал, но таким образом вы не можете использовать отладчик - вы зависите от отладки вывода на консоль. – akohout

ответ

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'

+0

Где я могу найти упомянутый контейнер для папки? – akohout

+0

в моем случае это 'C: \ Program Files (x86) \ JetBrains \ IntelliJ IDEA Community Edition 13.1.4 \ bin'. idea.properties не существует в моей среде, в этом случае вам нужно будет создать его. – Natan

+0

Удивительный! Моя версия gradle уже была up2date, но вставка опции, похоже, выполняет эту работу. Поэтому я принял ваш ответ как решение – akohout

0

Edit: ответ знакомства Натана для реального решения.

Если ответ не работает, вот обходной путь, который я использовал: Класс приложения предоставляет специальный маршрут, который при вызове просто убивает сервер. Для этого, основываясь на ответе in the google group, мы установили сервлет в приложении, определим маршрут и затем прослушаем его.

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