简体   繁体   中英

Spring autowires beans in different order when running from jar vs IntelliJ - Failed to start bean 'subProtocolWebSocketHandler' No handlers

I am building a spring web socket app and I am facing the following issue.

When I am running the app using IntelliJ everything is fine and the app starts up just fine.

When I am building the fat jar with spring boot maven plugin and starting up the app using java -jar the app is failing to start with the following error

Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers

at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler:start()

My spring web socket config looks like this

@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;
    }
}

The reason why the above error is happening is because when I run the app using the jar the method

@Autowired(required = false)
public void setConfigurers(List<WebSocketMessageBrokerConfigurer> configurers) {
    if (!CollectionUtils.isEmpty(configurers)) {
        this.configurers.addAll(configurers);
    }
}

inside DelegatingWebSocketMessageBrokerConfiguration which is supposed to autowire my WebSocketConfig is invoked after the

@Override
protected void registerStompEndpoints(StompEndpointRegistry registry) {
    for (WebSocketMessageBrokerConfigurer configurer : this.configurers) {
        configurer.registerStompEndpoints(registry);
    }
}

in DelegatingWebSocketMessageBrokerConfiguration which is causing the no handlers error. When I am starting the app through IntelliJ this is happening in reverse and everything is fine.

Does anyone have any idea why this is happening and what might be the reason causing it?

Is there any chance that loading classpath is happening in a different order in a jar vs in IntelliJ and that confuses spring?


EDIT

My WebSocketConfig class is slightly different than what I have put above. I am autowiring WebSocketMessageBrokerStats in it with setter injection. I have updated the code above. The reason why I didn't put this in my initial question is that I thought it was insignificant. But it is not. Answer is coming below...

Thanks a lot in advance

(let me know if you want more technical details from my side)

Nick

So after playing around with my code I figured out that the issues is the injection of the WebSocketMessageBrokerStats bean. Apparently this is causing WebSocketConfig bean (which is a special type of config since it implements WebSocketMessageBrokerConfigurer ) to be ready at a later stage in the Spring Context Initialisation leaving List<WebSocketMessageBrokerConfigurer> configurers empty when it is checked by the registerStompEndpoints() .

So the solution was to create a second configuration class and move the WebSocketMessageBrokerStats bean and all the operations on it in the new config file.

The above is fixing the jar file and I am able to run it with java -jar , however I have no idea how IntelliJ was able to run the app successfully without the fix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM