Resolución del Error 'javax.websocket.server.ServerContainer not available' en Aplicaciones Spring Boot con WebSocket

La integración de WebSocket en proyectos Spring Boot es una práctica común para habilitar comunicación en tiempo real. Sin embargo, al compilar o ejecutar pruebas, especialmente durante el proceso de empaquetado (build), es posible encontrarse con un error que impide el inicio correcto de la aplicación. Este problema se manifiesta con frecuencia a través de una excepción que indica que javax.websocket.server.ServerContainer no está disponible.

El mensaje de error típico en la consola o los logs del servidor se asemejará a la siguiente traza:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverEndpointExporter' defined in class path resource [com/example/config/WebSocketConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1694)
   ...
Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
   at org.springframework.util.Assert.state(Assert.java:73)
   at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterPropertiesSet(ServerEndpointExporter.java:107)
   ...
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[ERROR]   ApplicationTests.testContextLoads » IllegalState Failed to load ApplicationContext
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE

Este error se origina porque la clase ServerEndpointExporter de Spring, encargada de descubrir y registrar los puntos finales (endpoints) de WebSocket, requiere un entorno de contenedor de servlets completamente funcional para acceder al objeto ServerContainer. Cuando se ejceutan pruebas con @SpringBootTest por defecto, el contexto de aplicación podría no inicializar un contenedor de servlets completo o el entorno web necesario para WebSocket, llevanddo a que ServerContainer no sea encontrado.

La solución a este inconveniente radica en configurar la anotación @SpringBootTest en las clases de prueba para que inicie un entorno web adecuado. Al especificar webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, le indicamos a Spring Boot que inicie un servidor web incrustado (como Tomcat, Jetty o Undertow) en un puerto aleatorio, proporcionando así el ServerContainer necesario para la inicialización de los componentes de WebSocket.

A continuación, se muestra cómo aplicar esta configuración en una clase de prueba:

package com.example.testing;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class WebSocketApplicationIntegrationTest {

   @Test
   void applicationContextLoadsSuccessfully() {
       // Este test simplemente verifica que el contexto de Spring Boot
       // se carga correctamente con soporte para WebSocket.
       // No se requiere lógica adicional para demostrar la solución del error.
   }

   // Otros métodos de prueba para componentes WebSocket o servicios de la aplicación
}

Al incluir webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT en las pruebas que interactúan o dependen de la configuración de WebSocket, se asegura que el entorno de ejecución de la prueba replique las condiciones de un despliegue real, permitiendo que ServerEndpointExporter encuentre y utilice corectamente el javax.websocket.server.ServerContainer.

Etiquetas: SpringBoot WebSocket java testing ServerContainer

Publicado el 8-23 11:37