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.