WebSocket application doesn't work properly when deployed on Tomcat8 server
<p><strong>The Problem</strong></p>

<p>I'm trying to run this example with minimal changes in the source code: <a href="https://spring.io/guides/gs/messaging-stomp-websocket/" rel="nofollow">https://spring.io/guides/gs/messaging-stomp-websocket/</a></p>

<p>I have managed to run it using Eclipse and Maven, as well as a terminal window, again, with maven. I've also managed to package it into a .war file and run it in terminal using <code>java -jar myfile.war</code> It works as expected in those cases, i.e. localhost:8080 displays the simple interface and it connects and returns a greeting in the same window. The problem comes when I deploy the .war file to a tomcat8 server I have running on my RaspberryPi. In that case, the index.html displays, but the "Connect" button does nothing, which leads me to believe this is some sort of javascript related issue. The server works fine, btw, I have other stuff deployed on it.</p>

<p><strong>Things I've Tried</strong></p>

<ul>
<li>Edited the .war archive so that the index.html and the .js files are outside the WEB-INF directory, so that they may be accessible to the outside world. Problem persists.</li>
<li>Changed the script references to the .js files in index.html to</li>
</ul>

<p><div class="snippet" data-lang="js" data-hide="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="http://cdn.sockjs.org/sockjs-0.3.4.js"&gt;&lt;/script&gt;
&lt;script src="http://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.js"&gt;&lt;/script&gt;</code></pre>
</div>
</div>
</p>

<p>so that they may be delivered over a CDN, in case there was any problem with the .war file. The problem persists.</p>

<ul>
<li>Added extra functionality to the servlet so that it displays some data in a different directory just to make sure it works and this is not an issue with the .war file. Seems fine, but the above problem obviously persists.</li>
</ul>

<p><strong>Code</strong></p>

<p>Entry point</p>

<pre><code>@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
</code></pre>

<p>Greeting that will be returned.</p>

<pre><code>public class Greeting {

    private String content;

    public Greeting(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}
</code></pre>

<p>Controller</p>

<pre><code>@Controller
public class GreetingController {


    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(3000); // simulated delay
        return new Greeting("Hello, " + message.getName() + "!");
    }

}
</code></pre>

<p>Message to be sent</p>

<pre><code>public class HelloMessage {

    private String name;

    public String getName() {
        return name;
    }

}
</code></pre>

<p>WebSocket configuration</p>

<pre><code>@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

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

}
</code></pre>

<p>index.html</p>

<p><div class="snippet" data-lang="js" data-hide="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Hello WebSocket&lt;/title&gt;
    &lt;script src="sockjs-0.3.4.js"&gt;&lt;/script&gt;
    &lt;script src="stomp.js"&gt;&lt;/script&gt;
    &lt;script&gt;
        var stompClient = null;
        
        function setConnected(connected) {
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
            document.getElementById('response').innerHTML = '';
        }
        
        function connect() {
            var socket = new SockJS('/hello');
            stompClient = Stomp.over(socket);            
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/greetings', function(greeting){
                    showGreeting(JSON.parse(greeting.body).content);
                });
            });
        }
        
        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            setConnected(false);
            console.log("Disconnected");
        }
        
        function sendName() {
            var name = document.getElementById('name').value;
            stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name }));
        }
        
        function showGreeting(message) {
            var response = document.getElementById('response');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            p.appendChild(document.createTextNode(message));
            response.appendChild(p);
        }
    &lt;/script&gt;
&lt;/head&gt;
&lt;body onload="disconnect()"&gt;
&lt;noscript&gt;&lt;h2 style="color: #ff0000"&gt;Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
    Javascript and reload this page!&lt;/h2&gt;&lt;/noscript&gt;
&lt;div&gt;
    &lt;div&gt;
        &lt;button id="connect" onclick="connect();"&gt;Connect&lt;/button&gt;
        &lt;button id="disconnect" disabled="disabled" onclick="disconnect();"&gt;Disconnect&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id="conversationDiv"&gt;
        &lt;label&gt;What is your name?&lt;/label&gt;&lt;input type="text" id="name" /&gt;
        &lt;button id="sendName" onclick="sendName();"&gt;Send&lt;/button&gt;
        &lt;p id="response"&gt;&lt;/p&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
</p>

<p>pom.xml</p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;gs-messaging-stomp-websocket&lt;/artifactId&gt;
    &lt;version&gt;0.1.0&lt;/version&gt;

    &lt;parent&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
        &lt;version&gt;1.3.3.RELEASE&lt;/version&gt;
    &lt;/parent&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-websocket&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-messaging&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;properties&gt;
        &lt;java.version&gt;1.8&lt;/java.version&gt;
    &lt;/properties&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

    &lt;packaging&gt;war&lt;/packaging&gt;
&lt;/project&gt;
</code></pre>

<p>Log from last deployment</p>

<pre><code>  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.3.3.RELEASE)

2016-04-21 22:39:51.727  INFO 18022 --- [o-8080-exec-129] hello.Application                        : Starting Application on raspberrypi with PID 18022 (/var/lib/tomcat8/webapps/gs-messaging-stomp-websocket-0.1.0/WEB-INF/classes/hello/Application.class started by tomcat8 in /var/lib/tomcat8)
2016-04-21 22:39:51.800  INFO 18022 --- [o-8080-exec-129] hello.Application                        : No active profile set, falling back to default profiles: default
2016-04-21 22:39:52.752  INFO 18022 --- [o-8080-exec-129] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@167fc4: startup date [Thu Apr 21 22:39:52 EEST 2016]; root of context hierarchy
2016-04-21 22:40:09.630  INFO 18022 --- [o-8080-exec-129] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2016-04-21 22:40:16.208  INFO 18022 --- [o-8080-exec-129] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 23468 ms
2016-04-21 22:40:30.525  INFO 18022 --- [o-8080-exec-129] b.a.w.TomcatWebSocketContainerCustomizer : NonEmbeddedServletContainerFactory detected. Websockets support should be native so this normally is not a problem.
2016-04-21 22:40:40.343  INFO 18022 --- [o-8080-exec-129] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2016-04-21 22:40:40.360  INFO 18022 --- [o-8080-exec-129] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'errorPageFilter' to: [/*]
2016-04-21 22:40:40.363  INFO 18022 --- [o-8080-exec-129] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-04-21 22:40:40.366  INFO 18022 --- [o-8080-exec-129] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-04-21 22:40:40.369  INFO 18022 --- [o-8080-exec-129] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-04-21 22:40:40.372  INFO 18022 --- [o-8080-exec-129] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'requestContextFilter' to: [/*]
2016-04-21 22:40:41.904  INFO 18022 --- [o-8080-exec-129] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService  'clientInboundChannelExecutor'
2016-04-21 22:40:42.137  INFO 18022 --- [o-8080-exec-129] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService  'clientOutboundChannelExecutor'
2016-04-21 22:40:42.743  INFO 18022 --- [o-8080-exec-129] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService  'messageBrokerTaskScheduler'
2016-04-21 22:40:44.228  INFO 18022 --- [o-8080-exec-129] o.s.w.s.s.s.WebSocketHandlerMapping      : Mapped URL path [/hello/**] onto handler of type [class org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler]
2016-04-21 22:40:44.635  INFO 18022 --- [o-8080-exec-129] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService  'brokerChannelExecutor'
2016-04-21 22:40:49.712  INFO 18022 --- [o-8080-exec-129] .WebSocketAnnotationMethodMessageHandler : Mapped "{[/hello],messageType=[MESSAGE]}" onto public hello.Greeting hello.GreetingController.greeting(hello.HelloMessage) throws java.lang.Exception
2016-04-21 22:40:57.059  INFO 18022 --- [o-8080-exec-129] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@167fc4: startup date [Thu Apr 21 22:39:52 EEST 2016]; root of context hierarchy
2016-04-21 22:40:58.966  INFO 18022 --- [o-8080-exec-129] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-04-21 22:40:58.993  INFO 18022 --- [o-8080-exec-129] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity&lt;java.util.Map&lt;java.lang.String, java.lang.Object&gt;&gt; org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-04-21 22:40:59.092  INFO 18022 --- [o-8080-exec-129] o.s.w.s.c.a.WebMvcConfigurerAdapter      : Adding welcome page: ServletContext resource [/index.html]
2016-04-21 22:40:59.622  INFO 18022 --- [o-8080-exec-129] o.s.w.s.handler.SimpleUrlHandlerMapping  : Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
2016-04-21 22:40:59.948  INFO 18022 --- [o-8080-exec-129] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-04-21 22:40:59.950  INFO 18022 --- [o-8080-exec-129] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-04-21 22:41:01.167  INFO 18022 --- [o-8080-exec-129] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-04-21 22:41:06.289  INFO 18022 --- [o-8080-exec-129] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-04-21 22:41:06.561  INFO 18022 --- [o-8080-exec-129] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2016-04-21 22:41:06.570  INFO 18022 --- [o-8080-exec-129] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
2016-04-21 22:41:06.578  INFO 18022 --- [o-8080-exec-129] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]]
2016-04-21 22:41:06.597  INFO 18022 --- [o-8080-exec-129] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
2016-04-21 22:41:06.830  INFO 18022 --- [o-8080-exec-129] hello.Application                        : Started Application in 93.812 seconds (JVM running for 2602144.954)
Apr 21, 2016 10:41:07 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive /var/lib/tomcat8/webapps/gs-messaging-stomp-websocket-0.1.0.war has finished in 137,294 ms
2016-04-21 22:41:31.098  INFO 18022 --- [o-8080-exec-131] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2016-04-21 22:41:31.455  INFO 18022 --- [o-8080-exec-131] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 355 ms
2016-04-21 22:41:44.554  INFO 18022 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannelpool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
2016-04-21 23:11:44.549  INFO 18022 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannelpool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 1]
2016-04-21 23:41:44.549  INFO 18022 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannelpool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 2]
</code></pre>

<p>Link to my .war file</p>

<p><a href="http://s000.tinyupload.com/index.php?file_id=67742984079178858914" rel="nofollow">http://s000.tinyupload.com/index.php?file_id=67742984079178858914</a></p>

<p><strong>Final Thoughts</strong></p>

<p>Again, by process of elimination, either the .js libraries aren't importing properly, or there is something wrong with my server's WebSocket support. I'm really stuck on this one, any and all help would be appreciated.</p>