Servidor Web Jetty - Comportamento Inesperado

Boa tarde galera do GUJ,

Seguinte, estou com um problema um tanto estranho aqui, referente ao servidor Jetty. Por questões de experimentação e, principalmente, por existir boas referências deste servidor, optamos usá-lo em um projeto aparentemente simples (e é mesmo… Usamos JSP, Servlet, Filter, um pool de conexões com o PostgreSQL e "só" )

A questão, no entanto, é que a aplicação fica executando durante um tempo e, depois de algumas poucas requisições (poucas mesmo, mais ou menos umas 10) o servidor simplesmente "congela". É como se o Servlet que estava sendo executado caísse em algum método com um loop infinito ou algo que demora bastante tempo, pois todas as próximas requisições aguardam por essa primeira que causou a "parada" do servidor e por aí ficam; você tenta continuar navegando no site e nada mais funciona, o browser fica aguardando infinitamente uma resposta do Jetty, que não vem. Em seguida, tenho que parar o servidor (CTRL + C) e, depois disto, às vezes, aparecem algumas exceções. A primeira delas, quando acontece, é essa aqui:

java.lang.NullPointerException at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1323) at *****.filters.Controller.doFilter(Controller.java:213) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1323) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:476) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:480) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110) at org.eclipse.jetty.server.Server.handle(Server.java:346) at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589) at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1048) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:601) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214) at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:535) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529) at java.lang.Thread.run(Unknown Source)

A linha que corresponde à 213, no filtro Controller, é essa aqui:

chain.doFilter(request, response);

Para tentar ajudar um pouco, segue o arquivo de configuração da aplicação (web.xml):

<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>MasterPage</filter-name> <filter-class>*****.filters.MasterPage</filter-class> </filter> <filter> <filter-name>Controller</filter-name> <filter-class>*****.filters.Controller</filter-class> </filter> <filter> <filter-name>Security</filter-name> <filter-class>*****.filters.Security</filter-class> </filter> <filter-mapping> <filter-name>Controller</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>Security</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping> <filter-name>MasterPage</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <servlet> <servlet-name>Authenticator</servlet-name> <servlet-class>*****.servlets.Authenticator</servlet-class> </servlet> <servlet> <servlet-name>APIController</servlet-name> <servlet-class>*****.servlets.APIController</servlet-class> </servlet> <servlet> <servlet-name>Imager</servlet-name> <servlet-class>*****.servlets.Imager</servlet-class> </servlet> <servlet> <servlet-name>Mailer</servlet-name> <servlet-class>*****.servlets.Mailer</servlet-class> </servlet> <servlet-mapping> <servlet-name>Authenticator</servlet-name> <url-pattern>/authenticator/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>APIController</servlet-name> <url-pattern>/data/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Imager</servlet-name> <url-pattern>/images/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Mailer</servlet-name> <url-pattern>/mail/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <error-page> <error-code>400</error-code> <location>/error.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/error.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error.jsp</location> </error-page> <error-page> <error-code>401</error-code> <location>/error.jsp</location> </error-page> <resource-ref> <res-ref-name>jdbc/*****</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app>

O o recurso JDBC encontra-se aqui:

<?xml version="1.0" encoding="UTF-8"?> <Context antiJARLocking="true" path="/*****"> <Resource driverClassName="org.postgresql.Driver" maxActive="100" maxIdle="20" name="jdbc/*****" password="*****" type="javax.sql.DataSource" url="jdbc:postgresql://*****:5432/*****" username="*****"/> </Context>

E o arquivo de configuração do Jetty (jetty.xml) está aqui:

[code] <?xml version="1.0" ?>
<!DOCTYPE Configure (View Source for full doctype…)>

  • <!-- ===============================================================
    –>
  • <!-- Configure the Jetty Server
    –>
  • <!–
    –>
  • <!-- Documentation of this file format can be found at:
    –>
  • <!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax
    –>
  • <!–
    –>
  • <!-- Additional configuration files are available in $JETTY_HOME/etc
    –>
  • <!-- and can be mixed in. For example:
    –>
  • <!-- java -jar start.jar etc/jetty-ssl.xml
    –>
  • <!–
    –>
  • <!-- See start.ini file for the default configuraton files
    –>
  • <!-- ===============================================================
    –>
  • <Configure id=“Server” class=“org.eclipse.jetty.server.Server”>
  • <!-- ===========================================================
    –>
  • <!-- Server Thread Pool
    –>
  • <!-- ===========================================================
    –>
  • <Set name=“ThreadPool”>
  • <!-- Default queued blocking threadpool
    –>
  • <New class=“org.eclipse.jetty.util.thread.QueuedThreadPool”>
    <Set name=“minThreads”>10</Set>
    <Set name=“maxThreads”>200</Set>
    <Set name=“detailedDump”>false</Set>
    </New>
    </Set>
  • <!-- ===========================================================
    –>
  • <!-- Set connectors
    –>
  • <!-- ===========================================================
    –>
  • <Call name=“addConnector”>
  • <Arg>
  • <New class=“org.eclipse.jetty.server.nio.SelectChannelConnector”>
  • <Set name=“host”>
    <Property name=“jetty.host” />
    </Set>
  • <Set name=“port”>
    <Property name=“jetty.port” default=“80” />
    </Set>
    <Set name=“maxIdleTime”>300000</Set>
    <Set name=“Acceptors”>2</Set>
    <Set name=“statsOn”>false</Set>
    <Set name=“confidentialPort”>8443</Set>
    <Set name=“lowResourcesConnections”>20000</Set>
    <Set name=“lowResourcesMaxIdleTime”>5000</Set>
    </New>
    </Arg>
    </Call>
  • <!-- ===========================================================
    –>
  • <!-- Set handler Collection Structure
    –>
  • <!-- ===========================================================
    –>
  • <Set name=“handler”>
  • <New id=“Handlers” class=“org.eclipse.jetty.server.handler.HandlerCollection”>
  • <Set name=“handlers”>
  • <Array type=“org.eclipse.jetty.server.Handler”>
  • <Item>
    <New id=“Contexts” class=“org.eclipse.jetty.server.handler.ContextHandlerCollection” />
    </Item>
  • <Item>
    <New id=“DefaultHandler” class=“org.eclipse.jetty.server.handler.DefaultHandler” />
    </Item>
    </Array>
    </Set>
    </New>
    </Set>
  • <!-- ===========================================================
    –>
  • <!-- Server Pool Connection
    –>
  • <!-- ===========================================================
    –>
  • <New id=“PoolConnection” class=“org.eclipse.jetty.plus.jndi.Resource”>
    <Arg />
    <Arg>jdbc/*****</Arg>
  • <Arg>
  • <New class=“org.apache.commons.dbcp.BasicDataSource”>
    <Set name=“driverClassName”>org.postgresql.Driver</Set>
    <Set name=“url”>jdbc:postgresql://localhost:5432/</Set>
    <Set name=“username”>
    </Set>
    <Set name=“password”>******</Set>
    </New>
    </Arg>
    </New>
  • <!-- ===========================================================
    –>
  • <!-- extra options
    –>
  • <!-- ===========================================================
    –>
    <Set name=“stopAtShutdown”>true</Set>
    <Set name=“sendServerVersion”>true</Set>
    <Set name=“sendDateHeader”>true</Set>
    <Set name=“gracefulShutdown”>1000</Set>
    <Set name=“dumpAfterStart”>false</Set>
    <Set name=“dumpBeforeStop”>false</Set>
    </Configure>[/code]

Já testamos com o TomCat 7 (aliás, para constar, a versão do Jetty é a 7.4.5), em localhost, e a aplicação funciona normalmente. Estranho não? Suspeitam de algo?

Abraços!