Processo retornando NoRouteToHostException

Olá galera.

Tenho uma aplicação em JSP e Servlet (MVC / Fachada / DAO / ConnectionFactory) na qual um processo tem retornado NoRouteToHostException:

Exception in thread "main" excecoes.DAOException: Não foi possível abrir a conexão: org.postgresql.util.PSQLException: A tentativa de conexão falhou.
(...)
Caused by: excecoes.DAOException: org.postgresql.util.PSQLException: A tentativa de conexão falhou.
(...)
Caused by: org.postgresql.util.PSQLException: A tentativa de conexão falhou.
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:136)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:65)
	at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:116)
	at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30)
	at org.postgresql.jdbc3.Jdbc3Connection.<init>(Jdbc3Connection.java:24)
	at org.postgresql.Driver.makeConnection(Driver.java:369)
	at org.postgresql.Driver.connect(Driver.java:245)
	at java.sql.DriverManager.getConnection(DriverManager.java:582)
	at java.sql.DriverManager.getConnection(DriverManager.java:185)
	... 6 more
Caused by: java.net.NoRouteToHostException: Cannot assign requested address
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
	at java.net.Socket.connect(Socket.java:529)
	at java.net.Socket.connect(Socket.java:478)
	at java.net.Socket.<init>(Socket.java:375)
	at java.net.Socket.<init>(Socket.java:189)
	at org.postgresql.core.PGStream.<init>(PGStream.java:60)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:77)
	... 14 more
Java Result: 1

Eu utilizando Ubuntu 12.04 x64 e pelo que li por aí há um limite de conexões por host. A constatação disso se deu utilizando os comandos:

[list]Antes do processo iniciar:[/list]
$ netstat -a | grep postgres > conexoes_postgres
$ wc -l conexoes_postgres
3 conexoes_postgres

[list]Um tempo depois do processo sendo executado:[/list]
$ netstat -a | grep postgres > conexoes_postgres_on
$ wc -l conexoes_postgres_on
24534 conexoes_postgres_on

Ou seja, há 24534 conexões no estado TIME_WAIT.

Alguém tem alguma ideia de como solucionar isto?

Att.

Veja se sua placa de rede esta com IP da rede.

Estou processando a rotina localmente e o banco é local também (SGBD PostgreSQL 8.1). A rede está OK e a placa configurada.

Olá galera.

Fiz alguns testes e pelo que pude perceber o problema ocorre quando preciso obter um objeto a partir de uma classe DAO na qual já tenho uma conexão aberta. Ou seja, quando obtenho um objeto (ou uma coleção dele), abro uma conexão. Enquanto esta conexão está aberta, preciso obter um objeto que é atributo do primeiro, eu abro outra conexão no DAO.

Segue uma classe de exemplo:

[code]public class CidadeDAO {

private Connection con;

public CidadeDAO() throws DAOException {
try {
this.con = ConnectionFactory.abrirConexao();
} catch (Exception e) {
throw new DAOException("Não foi possível abrir a conexão: " + e.getLocalizedMessage(), e);
}
}

public Collection listar() throws DAOException {
PreparedStatement pstm = null;
ResultSet rs = null;
Collection cidades;

  String sql = "SELECT * FROM cidade";

  try {
     pstm = con.prepareStatement(sql);
     rs = pstm.executeQuery();

     cidades = new ArrayList<Cidade>();

     while (rs.next()) {
        int id = rs.getInt("codcidade");
        String nome = rs.getString("nome");
        String pkSiglaUf = rs.getString("uf");
        int idPais = rs.getInt("codpais");
        String codigoIbge = rs.getString("codmunicibge");
        String codigoIbgeAbrev = rs.getString("codabrevibge");
        
        UnidadeFederativa uf = obterUF(pkSiglaUf);
        
        Pais pais = obterPais(idPais);

        Cidade cidade = new Cidade(id, nome, uf, pais, codigoIbge, codigoIbgeAbrev);

        cidades.add(cidade);
     }

     return cidades;
  } catch (SQLException sqle) {
     throw new DAOException("Erro ao listar cidades: " + sqle.getLocalizedMessage(), sqle);
  } finally {
     ConnectionFactory.fecharConexao(con, pstm, rs);
  }

}

private static UnidadeFederativa obterUF(String sigla) throws DAOException {
UnidadeFederativaDAO ufDao = new UnidadeFederativaDAO();
return ufDao.obter(sigla);
}

private static Pais obterPais(int idPais) throws DAOException {
PaisDAO paisDao = new PaisDAO();
return paisDao.obter(idPais);
}
}[/code]
Quando eu preciso obter o objeto Cidade, abro uma conexão. Em CidadeDAO, preciso obter os objetos UF e Pais, que abrem mais duas conexões (UnidadeFederativaDAO e PaisDAO seguem a mesma estrutura de CidadeDAO).

Uma alternativa que me aconselharam a tentar é passar a conexão já estabelecida como parâmetro nos métodos que obtém outro objeto dentro do DAO. Ou seja, alterar o método da seguinte forma:

private static UnidadeFederativa obterUF(String sigla, Connection conn) throws DAOException { return UnidadeFederativaDAO.obter(sigla, conn); }
Onde este método sobrecarregado (obter()) seria estático.

Mas mesmo sendo estático, ao chamar este método estático, o construtor não abriria uma nova conexão?

Também me aconselharam a pesquisar sobre DataSource (Pool de Conexões).

Seria este um caminho?
Att.