Встроенная пристань обрабатывает запросы, запущенные из eclipse, но не развернутые

У меня есть приложение, встраивающее Jetty в качестве веб-сервера для размещения RESTful API. Я разрабатывал его в Eclipse на Ubuntu, и при запуске из IDE все отлично работает. Однако когда я упаковываю приложение и развертываю его на сервере, Jetty больше не отвечает на запросы.

Сервер открывает сокет на указанном мной порту, и включение ведения журнала INFO для spring-mvc показывает, что мой контроллер и его методы отображаются соответствующим образом. Запросы успешно открывают соединение, но затем данные не отправляются обратно, и фактически запрос никогда не попадает в мой код контроллера. Когда я закрываю приложение, я вижу, что все установленные соединения обрываются.

Я проверил, что все библиотеки в пути к классам для проекта Eclipse находятся в пути к классам при развертывании. Что еще я должен проверить, чтобы понять, почему он работает в Eclipse и не работает в другом месте?

Jetty версии 9, Java версии 1.7, Spring 3.2.2.

EDIT Отладка ведения журнала от Jetty, когда я делаю запрос:

2013-05-06 09:40:30,214 DEBUG qtp1215430550-35-acceptor-0-ServerConnector@263676bd{HTTP/1.1}{0.0.0.0:8090} [SelectorManager.java submit]-: <Queued change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Accept@1493f589>
2013-05-06 09:40:30,215 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java runChange]-: <Running change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Accept@1493f589>
2013-05-06 09:40:30,217 DEBUG qtp1215430550-29-selector-2 [AbstractEndPoint.java onOpen]-: <onOpen SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{false,null},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{null}{io=0,kio=0,kro=0}>
2013-05-06 09:40:30,220 DEBUG qtp1215430550-29-selector-2 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{false,null},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{null}{io=0,kio=0,kro=0} idle timeout check, elapsed: 3 ms, remaining: 29997 ms>
2013-05-06 09:40:30,221 DEBUG qtp1215430550-29-selector-2 [HttpConnection.java <init>]-: <New HTTP Connection HttpConnection@5465f4d9{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}>
2013-05-06 09:40:30,224 DEBUG qtp1215430550-29-selector-2 [AbstractConnection.java onOpen]-: <onOpen HttpConnection@5465f4d9{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}>
2013-05-06 09:40:30,227 DEBUG qtp1215430550-29-selector-2 [AbstractConnection.java fillInterested]-: <fillInterested HttpConnection@5465f4d9{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}>
2013-05-06 09:40:30,229 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java updateLocalInterests]-: <Local interests updated 0 -> 1 for SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{true,AC.ExReadCB@5465f4d9},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{HttpConnection@5465f4d9{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=1,kio=0,kro=0}>
2013-05-06 09:40:30,232 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java createEndPoint]-: <Created SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{true,AC.ExReadCB@5465f4d9},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{HttpConnection@5465f4d9{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=1,kio=0,kro=0}>
2013-05-06 09:40:30,233 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java runChange]-: <Running change org.eclipse.jetty.io.SelectChannelEndPoint$1@e56eabe>
2013-05-06 09:40:30,233 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java setKeyInterests]-: <Key interests updated 0 -> 1>
2013-05-06 09:40:30,234 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java select]-: <Selector loop waiting on select>
2013-05-06 09:40:30,234 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java select]-: <Selector loop woken up from select, 1/1 selected>
2013-05-06 09:40:30,234 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java setKeyInterests]-: <Key interests updated 1 -> 0>
2013-05-06 09:40:30,238 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java updateLocalInterests]-: <Local interests updated 1 -> 0 for SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{true,AC.ExReadCB@5465f4d9},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{HttpConnection@5465f4d9{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1}>
2013-05-06 09:40:30,238 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java runChange]-: <Running change org.eclipse.jetty.io.SelectChannelEndPoint$1@e56eabe>
2013-05-06 09:40:30,239 DEBUG qtp1215430550-29-selector-2 [QueuedThreadPool.java dispatch]-: <qtp1215430550{STARTED,2<=10<=10,i=0,q=4} dispatched AC.ExReadCB@5465f4d9>
2013-05-06 09:40:30,240 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java select]-: <Selector loop waiting on select>
2013-05-06 09:40:35,88 DEBUG Scheduler-702565976 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@238b5d33{/127.0.0.1:39894<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@1293d180{false,null},wf=WriteFlusher@269f3407{IDLE},it=30000}{HttpConnection@1e10cb60{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1} idle timeout check, elapsed: 29996 ms, remaining: 4 ms>
2013-05-06 09:40:35,96 DEBUG Scheduler-702565976 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@238b5d33{/127.0.0.1:39894<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@1293d180{false,null},wf=WriteFlusher@269f3407{IDLE},it=30000}{HttpConnection@1e10cb60{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1} idle timeout check, elapsed: 30005 ms, remaining: -5 ms>
2013-05-06 09:40:35,99 DEBUG Scheduler-702565976 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@238b5d33{/127.0.0.1:39894<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@1293d180{false,null},wf=WriteFlusher@269f3407{IDLE},it=30000}{HttpConnection@1e10cb60{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1} idle timeout expired>

РЕДАКТИРОВАТЬ 2 Мой сервер Jetty настроен на все компоненты spring:

<bean id="JettyServer" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">

<property name="connectors">
    <list>
        <bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <property name="port" value="8090"/>
        </bean>
    </list>
</property>

<property name="handler">
    <bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <property name="handlers">
            <list>
                <bean id="servletContextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
                    <property name="contextPath" value="/"/>
                    <property name="servletHandler">
                        <bean class="org.eclipse.jetty.servlet.ServletHandler">

                            <property name="servlets">
                                <list>
                                    <bean class="org.eclipse.jetty.servlet.ServletHolder">
                                        <property name="name" value="DefaultServlet"/>
                                        <property name="servlet">
                                            <bean class="com.company.project.api.DispatcherServletWrapper"/>
                                        </property>
                                    </bean>
                                </list>
                            </property>
                            <property name="servletMappings">
                                <list>
                                    <bean class="org.eclipse.jetty.servlet.ServletMapping">
                                        <property name="pathSpecs">
                                            <list><value>/</value></list>
                                        </property>
                                        <property name="servletName" value="DefaultServlet"/>
                                    </bean>
                                </list>
                            </property>
                        </bean>
                    </property>
                </bean>
                <bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
                    <property name="requestLog">
                        <bean class="org.eclipse.jetty.server.NCSARequestLog">
                            <constructor-arg value="/opt/company/logs/jetty-yyyy_mm_dd.log"/>
                            <property name="extended" value="false" />
                        </bean>
                    </property>
                </bean>
            </list>
        </property>
    </bean>
</property>
</bean>

Мне нужно, чтобы сервлет диспетчера знал об ApplicationContext, определяющем этот сервер Jetty, поэтому для справки мой класс DispatcherServletWrapper выглядит следующим образом:

package com.company.project.api;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class DispatcherServletWrapper extends DispatcherServlet implements ApplicationContextAware {

    private static final long serialVersionUID = -2281511575328213502L;
    private ApplicationContext appContext;

    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        this.appContext = arg0; 
    }

    protected WebApplicationContext createWebApplicationContext(WebApplicationContext arg0) {
        GenericWebApplicationContext wac = new GenericWebApplicationContext();
        wac.setParent(appContext);
        wac.refresh();

        return wac;
    }

}

person tdimmig    schedule 06.05.2013    source источник
comment
Я убедился, что моя среда разработки использует ту же JRE, что и рабочий сервер, и что путь к классам IDE точно соответствует пути к классам при запуске на сервере. Сервер работает под управлением CentOS 5.9. Я обнаружил, что сервер Jetty работает, как и ожидалось, обрабатывает мои запросы и возвращает результаты, как и ожидалось, на сервере CentOS 6.4.... При равенстве JRE и пути к классам мое приложение запускается не чем иным, как java -cp $( classpath переменная) com.company.project.Main, что еще отличается, что заставляет его работать в моей среде разработки Ubuntu и на сервере 6.4, но не 5.9?   -  person tdimmig    schedule 07.05.2013
comment
Недостаточно информации для прохождения. Вы не указали как запускать причал. Можете ли вы включить код о том, как вы запускаете причал? например, что вы делаете с экземпляром Server? вы server.start() затем server.join() или вы по-разному управляете потоком сервера в своем проекте?   -  person Joakim Erdfelt    schedule 08.05.2013
comment
Я переключился на Jetty 8 (который требовал другого класса для коннектора и никаких других изменений, кроме замены библиотеки), и все работает. Я до сих пор понятия не имею, какая идеальная комбинация штормов привела к тому, что он сломался с Jetty 9, который, как я уже упоминал, работал на нескольких других платформах. Но резервное копирование на Jetty 8 заставляет его работать на моей платформе развертывания, поэтому я пошел именно в этом направлении. Я бы закрыл / удалил этот вопрос, если бы знал, как это сделать. Тем не менее, спасибо за комментарий, я ценю, что кто-то проявляет интерес к помощи.   -  person tdimmig    schedule 09.05.2013


Ответы (1)


Ах, разъемы изменились с Jetty 9.

Начиная с Jetty 9, коннекторы состоят из цепочки ConnectionFactory, которая обеспечивает определение типа подключения и резервные варианты.

Это было сделано для поддержки современных реалий альтернативных типов веб-подключений (таких как расширения TLS, NPN, SPDY, WebSocket и даже подготовка к HTTP/2.0).

Вот несколько встроенных примеров:

Настройка стандартного соединителя HTTP в Jetty 9

package org.eclipse.jetty.embedded;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;

public class OneConnector
{
    public static void main(String[] args) throws Exception
    {
        // The Server
        Server server = new Server();

        // HTTP connector
        ServerConnector http = new ServerConnector(server);
        http.setHost("localhost");
        http.setPort(8080);
        http.setIdleTimeout(30000);

        // Set the connector
        server.addConnector(http);

        // Set a handler
        server.setHandler(new HelloHandler());

        // Start the server
        server.start();
        server.join();
    }
}

Настройка цепочки соединителей для SSL + NPN + SPDY/3 + SPDY/2 + HTTPS в Jetty 9

package org.eclipse.jetty.embedded;

import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy;
import org.eclipse.jetty.util.ssl.SslContextFactory;

public class SpdyConnector
{
    public static void main(String[] args) throws Exception
    {
        String jetty_home = System.getProperty("jetty.home","../../jetty-distribution/target/distribution");
        System.setProperty("jetty.home", jetty_home);

        // The Server
        Server server = new Server();

        // HTTP Configuration
        HttpConfiguration http_config = new HttpConfiguration();
        http_config.setSecureScheme("https");
        http_config.setSecurePort(8443);

        // HTTP connector
        ServerConnector http = new ServerConnector(server,new HttpConnectionFactory(http_config));        
        http.setPort(8080);
        server.addConnector(http);

        // SSL Context Factory for HTTPS and SPDY
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
        sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
        sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");

        // HTTPS Configuration
        HttpConfiguration https_config = new HttpConfiguration(http_config);
        https_config.addCustomizer(new SecureRequestCustomizer());

        // SPDY versions
        HTTPSPDYServerConnectionFactory spdy2 = 
            new HTTPSPDYServerConnectionFactory(2,https_config);

        HTTPSPDYServerConnectionFactory spdy3 = 
            new HTTPSPDYServerConnectionFactory(3,https_config,new ReferrerPushStrategy());

        // NPN Factory
        SPDYServerConnectionFactory.checkNPNAvailable();
        NPNServerConnectionFactory npn = 
            new NPNServerConnectionFactory(spdy3.getProtocol(),spdy2.getProtocol(),http.getDefaultProtocol());
        npn.setDefaultProtocol(http.getDefaultProtocol());

        // SSL Factory
        SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory,npn.getProtocol());

        // SPDY Connector
        ServerConnector spdyConnector = 
            new ServerConnector(server,ssl,npn,spdy3,spdy2,new HttpConnectionFactory(https_config));
        spdyConnector.setPort(8443);
        server.addConnector(spdyConnector);

        // Set a handler
        server.setHandler(new HelloHandler());

        // Start the server
        server.start();
        server.join();
    }
}
person Joakim Erdfelt    schedule 08.05.2013
comment
Я обновил свой вопрос примерами кода и XML, показывающим, как я запускаю свой сервер Jetty. Я упомянул о соединителе только для того, чтобы показать, что это единственная часть этой конфигурации, которую мне пришлось изменить при переходе обратно на Jetty 8 с 9. Сервер работал, как и ожидалось, с версией 9, в моей среде разработки и на сервере CentOS 6. . Это не сработало на сервере CentOS 5. Вернувшись к Jetty 8, он будет работать везде. Я не знаю, какой идеальный шторм программного обеспечения приводит к сбою версии моего проекта Jetty 9, но у меня нет времени разбираться в этом. - person tdimmig; 09.05.2013
comment
Я ценю ваши усилия в попытке помочь, но я не верю, что это была просто проблема с конфигурацией, учитывая, что он работал на 2 из 3 платформ, на которых я пробовал. - person tdimmig; 09.05.2013