Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从jar与IntelliJ运行时,Spring会以不同的顺序自动连接bean-无法启动bean';子目录WebSockEthandler';没有处理程序_Java_Spring_Spring Boot_Intellij Idea_Classpath - Fatal编程技术网

Java 从jar与IntelliJ运行时,Spring会以不同的顺序自动连接bean-无法启动bean';子目录WebSockEthandler';没有处理程序

Java 从jar与IntelliJ运行时,Spring会以不同的顺序自动连接bean-无法启动bean';子目录WebSockEthandler';没有处理程序,java,spring,spring-boot,intellij-idea,classpath,Java,Spring,Spring Boot,Intellij Idea,Classpath,我正在构建一个SpringWebSocket应用程序,我面临以下问题 当我使用IntelliJ运行应用程序时,一切正常,应用程序启动正常 当我使用SpringBootMaven插件构建胖jar并使用java-jar启动应用程序时,应用程序无法启动,出现以下错误 无法启动bean“subtocolwebsockethandler”;嵌套异常为java.lang.IllegalArgumentException:无处理程序 在org.springframework.web.socket.messag

我正在构建一个SpringWebSocket应用程序,我面临以下问题

当我使用IntelliJ运行应用程序时,一切正常,应用程序启动正常

当我使用SpringBootMaven插件构建胖jar并使用
java-jar
启动应用程序时,应用程序无法启动,出现以下错误

无法启动bean“subtocolwebsockethandler”;嵌套异常为java.lang.IllegalArgumentException:无处理程序

在org.springframework.web.socket.messaging.subtocolwebsockethandler:start()上

我的SpringWebSocket配置如下所示

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    private WebSocketMessageBrokerStats webSocketMessageBrokerStats;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic")
                .setHeartbeatValue(new long []{webSocketsProperties.getClientHeartbeatsSecs() * 1000, webSocketsProperties.getServerHeartbeatsSecs() * 1000})
                .setTaskScheduler(heartBeatScheduler());

        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS();
    }

    @Autowired
    public void setWebSocketMessageBrokerStats(WebSocketMessageBrokerStats webSocketMessageBrokerStats) {
        this.webSocketMessageBrokerStats = webSocketMessageBrokerStats;
    }
}
发生上述错误的原因是,当我使用jar方法运行应用程序时

@Autowired(required = false)
public void setConfigurers(List<WebSocketMessageBrokerConfigurer> configurers) {
    if (!CollectionUtils.isEmpty(configurers)) {
        this.configurers.addAll(configurers);
    }
}
在DelegatingWebSocketMessageBrokerConfiguration中,这会导致
无处理程序
错误。当我通过IntelliJ启动应用程序时,情况正好相反,一切正常

有人知道为什么会发生这种情况吗?原因可能是什么

是否有可能在jar中加载类路径的顺序与IntelliJ中加载的顺序不同,从而混淆了spring


编辑

我的
WebSocketConfig
类与我上面提到的略有不同。我正在使用setter注入自动连接WebSocketMessageBrokerStats。我已经更新了上面的代码。我没有在最初的问题中提到这一点的原因是我认为它无关紧要。但事实并非如此。答案就在下面

提前多谢

(如果您希望我方提供更多技术细节,请告知我)


Nick

所以在玩了我的代码之后,我发现问题在于
WebSocketMessageBrokerStats
bean的注入。显然,这导致
WebSocketConfig
bean(这是一种特殊类型的配置,因为它实现了
websocketmessagebrokerconfigure
)在Spring上下文初始化的稍后阶段准备就绪,
List configurers
在被
registerStompEndpoints()
检查时为空

因此,解决方案是创建第二个配置类,并将
WebSocketMessageBrokerStats
bean及其上的所有操作移动到新的配置文件中


上面正在修复jar文件,我可以使用
java-jar运行它,但是我不知道IntelliJ如何能够在没有修复的情况下成功运行应用程序。

我可以在
@Configuration
注释中看到
WebSocketConfig
类。它符合
@Component
@Service
类的条件,因此它应该在
setConfigurers
列表中作为bean自动连接,对吗?是的,它不会解决您的问题,但因为您是自动连接的,所以它应该是Component
@autowired(required=false)
为什么不需要它?不确定为什么spring将其作为可选项。我确实重写了该方法,并使其成为必需的,但没有任何区别。
@Override
protected void registerStompEndpoints(StompEndpointRegistry registry) {
    for (WebSocketMessageBrokerConfigurer configurer : this.configurers) {
        configurer.registerStompEndpoints(registry);
    }
}