首页 > 解决方案 > 如何修复,“类路径资源 [...] 无法打开,因为它不存在”在运行时使用 Spring

问题描述

当尝试在我们的 Springboot 应用程序中实现一个简单的 websocket 实现时,我一直遇到错误,很抱歉,因为我必须混淆一些与问题无关的信息。

Failed to load bean class: com.######.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist

当我尝试部署以进行调试和测试时,问题发生在运行时,而不是在 Maven 构建期间。

我已经在网上尝试了多个示例,用于使用 Stomp、SockJS 实现带有 Spring 和 JS/React 的 websockets,我总是想出某种形式的相同错误消息,其中 SwaggerConfig 有一个嵌套的 FileNotFoundException,因为我需要创建一些类我的服务器端的 websocket 连接。请注意,由于更广泛的项目依赖关系,我仅限于 Spring 版本4.0.9.RELEASE,因此我不能使用任何需要更新的 deps 的东西。

我的以下代码使用了https://www.javainuse.com/spring/boot-websocket中的最低限度示例

我的处理程序类:

import java.io.IOException;

import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class SocketTextHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException, JSONException {

        String payload = message.getPayload();
        JSONObject jsonObject = new JSONObject(payload);
        session.sendMessage(new TextMessage("Hi " + jsonObject.get("user") + " how may we help you?"));
    }

}

我的 websocket-config 类:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketTextHandler(), "/user");
    }

}

我的 Pom.xml 包含以下依赖项:

<properties>
    <spring.version>4.0.9.RELEASE</spring.version>
</properties>
...
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
      </dependency>
...
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
        <version>1.1.12.RELEASE</version>
</dependency>

最后,我的 React 应用程序使用此组件在连接时/如果连接时简单地显示数据:

const WebSocketStream = () => {
    const [text, setText] = React.useState<string>("Hello!");
    const [connected, setConnected] = React.useState<boolean>(false);
    let ws:WebSocket;

    const connect = () => {
        ws = new WebSocket('ws://localhost:8080/app/user');
        ws.onmessage = (data) => {
            setText(data.data);
        }
        setConnected(true);
    };

    const disconnect = () => {
        if (ws != null) {
            ws.close();
        }
        setConnected(false);
        console.log("Websocket is in disconnected state");
    };

    const sendMessage = () => {
        const data = JSON.stringify({
            'user' : 'I was here'
        });
        ws.send(data);
    }

    return (
        <WebSocketStreamWrapper>
            {text + "\n"}
            {connected ? "Connected!" : "Not connected :("}
            <Button onClick={connect}>Connect</Button>
            <Button onClick={sendMessage}>Send Message</Button>
            <Button onClick={disconnect}>Disconnect</Button>
        </WebSocketStreamWrapper>
    );
};

export default WebSocketStream;

我希望服务器至少能够启动并运行,这样我就可以从前端使用 websocket 进行连接。这是完整的错误消息,

16:16:05,380 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-4) Context initialization failed: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:163) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:305) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:611) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) [org.springframework-spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) [org.springframework-spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [org.springframework-spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:173) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:193) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    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)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_202]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_202]
    at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_202]
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172) [com.business.ws-viz-script-common-8.9.1-20190523.213339-28.jar:]
    at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50) [com.business.ws-viz-script-common-8.9.1-20190523.213339-28.jar:]
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:98) [com.business.ws-viz-script-common-8.9.1-20190523.213339-28.jar:]
    at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102) [com.business.ws-viz-script-common-8.9.1-20190523.213339-28.jar:]
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:93) [com.business.ws-viz-script-common-8.9.1-20190523.213339-28.jar:]
    at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:566) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:741) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:285) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:219) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:177) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:253) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:219) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:177) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:159) [org.springframework-spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
    ... 18 more

16:16:05,389 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./app: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./app: Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_202]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_202]
    at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_202]
Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:222)
    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: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:163)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:305)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:611)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:173)
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:193)
    ... 7 more
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
    at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50)
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:98)
    at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:93)
    at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:566)
    at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:741)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:285)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:219)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:177)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:253)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:219)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:177)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:159)
    ... 18 more

16:16:05,399 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 4) JBAS014613: Operation ("deploy") failed - address: ([("deployment" => "app-ear-10.0.0-SNAPSHOT.ear")]) - failure description: {"JBAS014671: Failed services" => {"jboss.undertow.deployment.default-server.default-host./app" => "org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./app: Failed to start service
    Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    Caused by: java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist"}}
16:16:05,401 ERROR [org.jboss.as.server] (management-handler-thread - 4) JBAS015870: Deploy of deployment "app-ear-10.0.0-SNAPSHOT.ear" was rolled back with the following failure message: 
{"JBAS014671: Failed services" => {"jboss.undertow.deployment.default-server.default-host./app" => "org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./app: Failed to start service
    Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.business.swagger.SwaggerConfig; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist
    Caused by: java.io.FileNotFoundException: class path resource [org/springframework/web/socket/handler/TextWebSocketHandler.class] cannot be opened because it does not exist"}}

标签: springreactjsmavenwebsocket

解决方案


问题出在子神器 poms 上。如果其他人遇到此问题,请检查您的父依赖项是否也在您的子 pom 中,我没有运行根本原因分析,但将依赖项添加到子 pom 也解决了这个问题。


推荐阅读