2

So I'm looking to upgrade my projects from spring boot 1.1.9.RELEASE to 1.2.1.RELEASE.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>

However, on startup, I gained:

Exception in thread "Thread-0" org.springframework.context.ApplicationContextException: Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:176)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
        at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:770)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
        at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:95)
        at com.springagain.Application.run(Application.java:17)
Caused by: java.lang.IllegalArgumentException: No handlers
        at org.springframework.util.Assert.isTrue(Assert.java:65)
        at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:234)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        ... 8 more

Here's how my websocket configuration looks

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration extends
        AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableStompBrokerRelay("/queue/", "/topic/");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // TODO Auto-generated method stub

    }

}

Switching back to 1.1.9.RELEASE of only the spring-boot-starter-websocket dependency (and keeping all other spring boot dependencies at 1.2.1.RELEASE and spring core at 4.1.4), the exception disappears.

Looks like a bug but can someone confirm?

UPDATE: More context - this is from a backend server code - no websocket clients connect to it. Intention is to publish 'interesting' events over RabbitMQ, which are then available to clients from front end servers that expose a websocket endpoint. Code on my front end servers add the endpoint with Socksjs support:

public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/push").withSockJS();
}

From that standpoint, either my understanding is fundamentally flawed :), OR Spring has become overzealous in checking that there should be a websocket endpoint always.

Raghu
  • 1,140
  • 1
  • 14
  • 22
  • @andy-wilkinson - Thanks. I changed my code to ```@Configuration public class WebsocketConfiguration extends AbstractMessageBrokerConfiguration{ @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/queue/", "/topic/"); } }``` on the backend and that works (ws messages are delivered to the browser). However, I if I try with enableSimpleBroker instead of enableStompBrokerRelay as you suggest, then no messages are delivered to the browser. I'll dig around further as well. – Raghu Feb 12 '15 at 17:26

1 Answers1

3

The root of the problem is that you haven't configured any endpoints in registerStompEndpoints. An application that's trying to use STOMP, but has not configured any STOMP endpoints, won't work correctly.

When you're using Spring Boot 1.1.9.RELEASE you'll have some Spring Framework 4.0.x jars on your classpath. Spring Framework 4.0.x's WebSocket support doesn't notice the misconfiguration and allows your app to start even though it won't work. Spring Framework 4.1's WebSocket support notices this misconfiguration and throws an exception, thereby alerting you to the problem.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • Hmm - actually that's intentional. The code is from my backend server which isn't exposed to HTTP clients. It's only role is to publish 'interesting' events over rabbitmq broker. So on my front end project, I have public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/push").withSockJS(); } – Raghu Feb 12 '15 at 14:39
  • If you don't care about receiving inbound STOMP messages, then you're configuring more than you need. Try extending `AbstractMessageBrokerConfiguration` and removing `@EnableWebSocketMessageBroker`. Actually, you probably don't want the relay either. As its name suggests it's intended to relay STOMP messages from WebSocket clients to a message broker. You don't have any clients, so there's nothing to relay. – Andy Wilkinson Feb 12 '15 at 15:20