【问题标题】:Spring Boot Websockets in WildflyWildfly 中的 Spring Boot Websockets
【发布时间】:2014-11-05 16:17:05
【问题描述】:

您好,我需要将 Spring Boot 应用程序部署到 Wildfly 8.1 中,但出现以下异常:

原因:java.lang.RuntimeException: java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer 无法转换为 io.undertow.websockets.jsr.ServerWebSocketContainer 在 io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:219) 在 org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:87) 在 org.wildfly.extension.undertow.deployment.UndertowDeploymentService.start(UndertowDeploymentService.java:72) 在 org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.2.Final.jar:1.2.2.Final] 在 org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.2.Final.jar:1.2.2.Final] ... 3 更多 引起:java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer 不能转换为 io.undertow.websockets.jsr.ServerWebSocketContainer 在 io.undertow.websockets.jsr.Bootstrap$WebSocketListener.contextInitialized(Bootstrap.java:69) 在 io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:173) 在 io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:190) ... 7 更多

似乎我的 websockets 和消息传递设置可能是罪魁祸首? 我在看这个https://github.com/joshlong/boot-examples/issues/2 并且提议的解决方案似乎都不适合我。以下是我的 pom 中的依赖项:

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

<dependencies>

    <!--Testing-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>${apache.httpcomponents.version}</version>
    </dependency>

    <!-- Spring -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-websocket</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-messaging</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring4</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

    <!--Database-->
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901.jdbc4</version>
    </dependency>
</dependencies>

我也尝试使用直接 spring-boot-starter-websocket,但得到了同样的结果。 这也是我的 websocket 配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
    super.configureMessageBroker(registry);
    registry.enableSimpleBroker("/ssp");
    registry.setApplicationDestinationPrefixes("/inc");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/update/applications");
}
}

感谢您抽出宝贵时间阅读本文。我将不胜感激任何帮助。 此外,这是我的第一个启动应用程序。 :/

【问题讨论】:

  • 我在使用 gradle 构建战争时也遇到了同样的问题。我能够通过使用providedCompile 代替spring-boot-starter-tomcat 而不是compile 来解决问题。

标签: spring websocket spring-boot wildfly spring-websocket


【解决方案1】:

你需要排除 tomcat-embed-websocket

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-websocket</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

【讨论】:

  • 很好,很高兴帮助。
【解决方案2】:

spring-boot-starter-web 和 spring-boot-starter-websocket 默认包含 spring-boot-starter-tomcat 所以排除 tomcat,如下所示

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring-boot.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
        <version>${spring-boot.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

并包含undertow,确保tomcat在类路径中不存在。

【讨论】:

    【解决方案3】:

    我不确定,但是你在 websockets 周围的 POM 应该是这样的:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-websocket</artifactId>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    

    spring-messagingspring-websocketjackson-databindspring-boot-starter-web 是多余的。

    还有spring-boot-starter-thymeleaf

    但我认为你的根源是tomcat-embed-websocket

    【讨论】:

    • 非常感谢您的回复。我更改了我的 pom 以消除冗余的 deps 并添加了 tomcat-embed-websocket,但仍然遇到上述异常。我猜容器期待undertow web socket实现?为什么我的 spring boot 应用程序在 boot 应该控制整个容器时尝试使用 undertow,不是吗?
    • 当然没有。 Spring 只是委托给目标容器实现,类似于 JTA。您应该检查应用程序的类路径(WEB-INF/lib ?)以查找 Tomcat jar,并查看哪些 deps 也应排除在外。
    • 艺术,非常感谢! Intellij 没有同步我的库。我的菜鸟错误。但是我确实必须重新添加 spring-messaging。我想我需要它直接用于我的控制器中的 MessageMapping 注释。但无论如何,我现在很好。再次感谢!
    【解决方案4】:

    使用以下命令查找包含spring-boot-starter-tomcat的所有依赖项:

    mvn dependency:tree -Dincludes=org.springframework.boot:spring-boot-starter-tomcat
    

    从该命令列出的所有依赖项中排除 Tomcat 启动器。

    之后,您可能需要添加 javax.servlet-api 作为提供的依赖项:

    <dependency>
        <artifactId>javax.servlet</artifactId>
        <groupId>javax.servlet-api</groupId>
        <scope>provided</scope>
    </dependency>
    

    有此问题的 Gradle 用户:查看此票证上的 cmets:https://github.com/spring-projects/spring-boot/issues/6166

    【讨论】:

      【解决方案5】:

      对我来说,spring-boot-starter-websocket 和 spring-boot-starter-web 默认包含 spring-boot-starter-tomcat 所以排除 tomcat,如下图没有 spring boot 版本:

      <dependency>  
              <groupId>org.springframework.boot</groupId>  
              <artifactId>spring-boot-starter-web</artifactId>  
              <exclusions>
                  <exclusion>
                      <groupId>org.apache.tomcat.embed</groupId>
                      <artifactId>tomcat-embed-websocket</artifactId>
                  </exclusion>
              </exclusions>
          </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-websocket</artifactId>
              <exclusions>
                  <exclusion>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-tomcat</artifactId>
                  </exclusion>
              </exclusions>
          </dependency>
      

      【讨论】:

        【解决方案6】:

        嗯,上面给出的解决方案都不适合我。

        实际上是父版本中的版本造成了问题。

        不工作:

            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.1.3.RELEASE</version>
                <relativePath /> <!-- lookup parent from repository -->
            </parent>
        

        工作:

             <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.5.0</version>
                <relativePath /> <!-- lookup parent from repository -->
            </parent>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-07
          • 1970-01-01
          • 2016-07-24
          • 1970-01-01
          • 2020-07-04
          • 2021-03-26
          • 1970-01-01
          • 2019-10-19
          相关资源
          最近更新 更多