showmessagedialog - mostrar mensaje de error en java
¿Qué es java.io.EOFException? Mensaje: No se puede leer la respuesta del servidor. Se espera que lea 4 bytes, lea 0 bytes (6)
Esta es la excepción EndOfFileException en java, que ocurre cuando el punto de inicio del cursor está en el punto final o cuando se cierra la conexión de la base de datos debido a alguna excepción inesperada.
Esta pregunta se ha formulado un par de veces en SO y muchas veces en otros sitios. Pero no obtuve ninguna respuesta satisfactoria.
Mi problema:
Tengo una aplicación web Java que utiliza JDBC simple para conectarse a la base de datos mysql a través del servidor de aplicaciones Glassfish .
He utilizado la agrupación de conexiones en el servidor glassfish con las siguientes configuraciones:
Tamaño inicial de la piscina: 25
Tamaño máximo de la piscina: 100
Cantidad de cambio de tamaño de la piscina: 2
Tiempo de inactividad: 300 segundos
Tiempo máximo de espera: 60,000 milisegundos
La aplicación se implementó durante los últimos 3 meses y también funcionaba sin problemas.
Pero desde los últimos 2 días, se produce el siguiente error al momento de iniciar sesión.
StackTrace parcial
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed due to underlying exception/error:
** BEGIN NESTED EXCEPTION **
com.mysql.jdbc.CommunicationsException
MESSAGE: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
STACKTRACE:
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3256)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1313)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1448)
............
............
my application traces....
¿Qué causó este error de repente? He perdido mucho tiempo para esto.
EDITAR: El problema persiste incluso después de reiniciar el servidor. Según DBA dos de las configuraciones de servidor mysql importantes son:
wait_timeout: 1800 segundos
connect_timeout: 10 segundos
NOTA: otras aplicaciones implementadas en el mismo servidor que se conectan a la misma base de datos y usan diferentes grupos funcionan sin problemas.
EDIT-2: Después de leer muchas cosas y de esperar algún resultado positivo, realicé estos cambios en mi grupo de conexiones.
Tiempo máximo de espera: 0 (anteriormente era 60 segundos)
Validación de conexión: requerida
Método de validación: tabla
Nombre de tabla: Demo
Validar casi una vez: 40 segundos
Intentos de reintento de creación: 1
Intervalos de reintento: 5 segundos
Uso máximo de la conexión: 5
Y esto funcionó ya que la aplicación se ejecuta durante 3 días constantemente. Pero obtuve un resultado muy extraño e interesante de esto. Mientras supervisaba el grupo de conexiones, encontré estas cifras:
NumConnAcquired: 44919 Cuenta
NumConnReleased: 44919 Count
NumConnCreated: 9748 Count
NumConnDestroyed: 9793 Count
NumConnFailedValidation: 70 Count
NumConnFree: 161 Count
NumConnUsed: -136 Count
¿Cómo puede NumConnFree
convertirse en 161 ya que tengo el Maximum Pool Size = 100
?
¿Cómo puede NumConnUsed
convertirse en -136, un número negativo ?
¿Cómo puede NumConnDestroyed
> NumConnCreated
?
La conexión ha fallado, posiblemente debido a un tiempo de espera inactivo del cortafuegos, etc. Si no tiene su controlador JDBC configurado para reconectarse en caso de fallo, este error no desaparecerá a menos que abra una nueva conexión.
Si está utilizando un grupo de conexión de base de datos ( está utilizando uno, ¿no?), Entonces probablemente desee habilitar sus funciones de comprobación de conexión, como emitir una consulta para verificar si la conexión funciona antes de devolverla a la aplicación. En Apache commons-dbcp, esto se llama validationQuery
y a menudo se configura como algo simple como SELECT 1
.
Dado que está utilizando MySQL, debe usar una consulta "ping" específica de Connector / J que sea más liviana que emitir realmente una consulta SQL verdadera y establecer su consulta de validación a /* ping */ SELECT 1
(la parte ping necesita para ser exactos ).
Lo más probable es que la base de datos se haya reiniciado o que la conexión de red a la base de datos se haya roto (p. Ej., Se agotó el tiempo de espera de una conexión NAT) ... y su aplicación web está intentando usar una conexión obsoleta de la base de datos.
Si el problema persiste después de reiniciar el contenedor web, podría ser algo más serio.
Usted preguntó lo siguiente:
How can the NumConnFree become 161 as I have Maximum Pool Size = 100 ?
How can the NumConnUsed become -136, a negative number ?
How can the NumConnDestroyed > NumConnCreated ?
A primera vista, estos no tienen sentido. Sin embargo, simplemente podrían ser el resultado de que algunos contadores de uso se actualicen de una manera que no sea segura para subprocesos. Esto no está necesariamente relacionado con su problema original.
Podría ser un problema relacionado con el Firewall.
Si bien no tengo soluciones definitivas, parece que algo interfiere en la comunicación entre el servidor de la aplicación y db. A continuación, hay algunas cosas que puede intentar para aislar los problemas:
Trate de determinar si este es un problema de mysql o problema con el código de java. Intente conectarse a mysql utilizando la herramienta de línea de comandos desde el mismo host que el servidor de la aplicación y emita un SQL similar para realizar el inicio de sesión. Pruebe usando un código simple de Java que realiza una selección, impleméntelo en la misma infraestructura, vea lo que sucede, etc. También verifique el registro del servidor de MySQL, vea si puede encontrar algo útil.
Hay dos formas en que se cierra una conexión inactiva: mediante el código del grupo de conexiones que se ejecuta dentro del servidor de la aplicación o mediante el propio mysql. Asegúrate de verificar la configuración en ambos lados
Verifique si alguna configuración de infraestructura de red ha cambiado recientemente. ¿Hubo alguna nueva regla de firewall que interfiera con la conectividad mysql del servidor de aplicaciones <->? ¿Hubo alguna configuración que prohíba abrir la conexión TCP al ralentí más tiempo que X?
Pruebe una biblioteca de agrupación de conexiones diferente solo para eliminar la posibilidad de que sea la agrupación de conexiones
Buena suerte
Tuve este problema, pero no me fue posible realizar cambios en la configuración de la base de datos MySQL. Por lo tanto, me aseguré de que en mi clase de conector sql la conexión siempre esté cerrada antes de que se inicie de nuevo. Algo como:
public static Connection getConnection() {
if (DatabaseConnnector.conn == null) {
initConn();
} else {
try {
DatabaseConnnector.conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
initConn();
}
return DatabaseConnnector.conn;
}
Y esto resolvió el problema.