Spring Boot在Wildfly中的Websockets

32

嗨,我需要将我的Spring Boot应用部署到Wildfly 8.1中,但是我遇到了以下异常:

Caused by: java.lang.RuntimeException: java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to io.undertow.websockets.jsr.ServerWebSocketContainer at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:219) at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:87) at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.start(UndertowDeploymentService.java:72) at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.2.Final.jar:1.2.2.Final] at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.2.Final.jar:1.2.2.Final] ... 3 more Caused by: java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to io.undertow.websockets.jsr.ServerWebSocketContainer at io.undertow.websockets.jsr.Bootstrap$WebSocketListener.contextInitialized(Bootstrap.java:69) at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:173) at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:190) ... 7 more

看起来我的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构建WAR文件时,我也遇到了同样的问题。但是,我通过将spring-boot-starter-tomcat的依赖范围从compile更改为providedCompile来解决了这个问题。 - Tariq M Nasim
可以通过从类路径中排除 spring-boot-starter-tomcat:jar 来解决上述问题 参考 - Prasanth Rajendran
6个回答

54

您需要排除 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>

很好,帮助你是一种愉悦。 - jlgranda

15

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在类路径中不存在。


4
我不确定,但是你的关于WebSockets的POM应该像这样:

我不确定,但是你的关于 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文件以消除冗余依赖项,并添加了tomcat-embed-websocket,但仍然遇到上述异常。我猜容器期望使用undertow的web socket实现?为什么我的Spring Boot应用程序会尝试使用undertow,当Boot应该控制整个容器呢? - Chris Stier
当然不是。Spring只是委托给目标容器实现,类似于JTA。您应该检查应用程序的类路径(WEB-INF/lib?)中的Tomcat JAR文件,并查看哪些依赖项也应该被排除。 - Artem Bilan
Art,非常感谢!Intellij没有同步我的库。这是我犯的新手错误。但是我确实需要重新添加spring-messaging。我认为我需要它直接在我的控制器中用于我的MessageMapping注释。但无论如何,现在我很好了。再次感谢! - Chris Stier

2
使用以下命令查找所有包含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 用户遇到此问题:请查看此票的评论:https://github.com/spring-projects/spring-boot/issues/6166

0

嗯,以上提供的解决方案都没有对我起作用。

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

不起作用:

    <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>

0

对于我来说,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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接