6

I am trying to deploy a Spring Boot (2.0.5) web application (war) with web sockets to a Tomcat 8.5.37 server, it previously worked with Tomcat 7. My web socket configuration is throwing the exception and preventing the application from starting. Am I missing some type of configuration in Spring or Tomcat? Something that is no longer available since I upgraded Tomcat?

I am able to run locally (through eclipse and eclipse's Tomcat v8.5), but when I try to deploy to our Tomcat server on our qa enviroment I get the following:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/soft/core/app/configuration/WebSocketConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:740)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:157)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:137)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5267)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext

I was able to isolate to cause to this bean, if I remove this bean the app starts up:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer{
...
...
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(1024 * 1024); // 1 MB
        return container;
    }
}

This is my Spring-BOM.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-messaging</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

This is my pom.xml

   <packaging>war</packaging>
   ...
   <dependencies>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.2.8</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>net.sourceforge.jtds</groupId>
        <artifactId>jtds</artifactId>
    </dependency>
    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j-cypher-compiler-2.1</artifactId>
        <version>2.1.5</version>
    </dependency>
    <!-- jsoup HTML parser library @ https://jsoup.org/ -->
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.11.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-net</groupId>
        <artifactId>commons-net</artifactId>
        <version>3.3</version>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.6.0</version>
    </dependency>              
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.8.0</version>
        <scope>test</scope>
    </dependency>        
</dependencies>
Phil Ninan
  • 1,108
  • 1
  • 14
  • 23
  • The error implies that your servlet container is not enabled for web sockets. Do the web sockets work without `ServletServerContainerFactoryBean` problematic bean? – Karol Dowbecki Jan 08 '19 at 22:45
  • [different server but may be related...](https://stackoverflow.com/questions/32074948/no-javax-websocket-server-servercontainer-servletcontext-attribute-glassfish) – mavriksc Jan 08 '19 at 22:45
  • The web sockets work without the `ServletServerContainerFactoryBean`, but I need to set a larger max text message buffer. – Phil Ninan Jan 08 '19 at 22:47
  • You're trying to deploy a standalone executable jar with an embedded Tomcat, right? That's what your pom seems to be implying at least. – Roddy of the Frozen Peas Jan 08 '19 at 22:48
  • I am deploying a war. I will update my question. – Phil Ninan Jan 08 '19 at 22:51
  • What do you mean "I'm able to run locally"? If you take a fresh local install of Tomcat 8.5 and deploy the WAR locally will it work? – Karol Dowbecki Jan 08 '19 at 23:01
  • When I say run locally I mean through eclipse, which is also using Tomcat 8.5. – Phil Ninan Jan 08 '19 at 23:05

4 Answers4

5

Had same issue for Tomcat 9.0.20 and Tomcat 9.0.21 with SpringBoot 2.1.1 to SpringBoot 2.1.6. Found some discussion here: https://github.com/spring-projects/spring-boot/issues/15746

They seems found problem with some kind tomcat version. Anyway.

What helped me was to add web.xml to catalog WEB-INF and paste following snippet:

<absolute-ordering>
    <name>spring_web</name>
</absolute-ordering>

Spring documentation: WebSocket and Spring

Paweł Głowacz
  • 2,926
  • 3
  • 18
  • 25
3

After many years, we were finally able to resolve this issue by updating to the latest minor version of Apache Tomcat 8 (8.5.78).

This is an alternative option to my previous answer of downgrading to an unstable Apache Tomcat 8 version.

Phil Ninan
  • 1,108
  • 1
  • 14
  • 23
1

This is not the best answer, but I was able to fix this issue by using Apache Tomcat 8.5.4 which does not seem to be stable. I am unsure on WHY this fixes these issues, but my best guess is something to do with the Tomcat\lib libraries.

I am using Java 8, which Apache says to use Tomcat9, but I received the same exception using that version as well.

Phil Ninan
  • 1,108
  • 1
  • 14
  • 23
  • got the same issue with my tomcat server (running on ubuntu 18.04), there was an urgent update (auto) and my tomcat got updated to `8.5.39`... now after restarting my tomcat service... my application won't start and got the same issue as yours. I tried version `8.5.40` with no luck. I will try `8.5.4` and see if it works. – Borgy Manotoy Apr 17 '19 at 11:57
1

I encountered this issue as well and inserting the following snippet into my web.xml file did not work for me:

<absolute-ordering>
    <name>spring_web</name>
</absolute-ordering>

However, I did fix it by downloading the most recent Apache Tomcat (went from 9.0.30 to 9.0.34).

Squinshee
  • 27
  • 5