vaadinvaadin7

Adding second UI to Vaadin 7 app causes problems


I have a Vaadin 7 application where I originally had just one UI. The following things happened, which I did not mind and even liked:

  1. When installed new WAR file, all browser tabs currently opened to that URL gave the black "Connection failed" or "Session expired" error, forcing me to refresh. Also, I would often get a "server loading" error in the upper right corner while the application deployed. This one is kind of hard to explain, but hopefully this makes sense. None of this was triggered by my code directly, all of it was behavior I got from Vaadin out of the box.
  2. If I was logged in to the same website (and same user) in multiple browser tabs, and then logged out of one tab, my code to logout/inactivate all tabs worked great - they all went back to the login screen, as I coded them to.

At that time, I had web.xml as follows:

web-app id="WebApp_ID" version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>vaadinwebsite</display-name>

    <context-param>
        <description>Vaadin production mode</description>
        <param-name>productionMode</param-name>
        <param-value>${productionMode}</param-value>
    </context-param>
    <servlet>
        <!-- <servlet-name>WmsUIServlet</servlet-name> -->
        <servlet-name>WmsServlet</servlet-name>
        <servlet-class>com.mobiwms.website.WmsServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>com.mobiwms.website.WmsUI</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <!-- <servlet-name>WmsUIServlet</servlet-name> -->
        <servlet-name>WmsServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
<!-- Uncomment if add more than one UI 
    <servlet-mapping>
        <servlet-name>Vaadintutorial</servlet-name>
        <url-pattern>/VAADIN/*</url-pattern>
    </servlet-mapping>
 -->
... <!-- some other stuff-->
</web-app>

I recently added a second UI, which meant I needed to tweak the path of the first UI. So I did the following:

  1. Changed web.xml so it uses 3.0, and comment out servlet references in web.xml so it would use WebServlet annotations in the code.
  2. Changed the url pattern of my first UI from @WebServlet(urlPatterns = "/*", name = "WmsServlet", asyncSupported = true) to @WebServlet(urlPatterns = {"/*", "/VAADIN/*"}, name = "WmsServlet", asyncSupported = true), as per the documentation. So this makes it so the "root" application is my main UI, like it was when I only had one UI. As per my web.xml snippet above, I always had a url pattern of "/*".
  3. Added a new UI and url pattern using @WebServlet(urlPatterns = "/Registration/*", name = "WmsRegistrationServlet", asyncSupported = true).

Now I am getting the following weirdness:

  1. Installing a new WAR does not force me to refresh. In other words, I don't even notice I need to refresh until I start doing something, at which point I get the normal black "communication failed", like normal.
  2. When I am logged in on two tabs and logout, it definitely invalidates the session in the other tab (I see the black "communication failed" error), but it does not go back to the login screen like it used to.
  3. At various times we see a failed to load widgetset error.
  4. On occasion, when we are doing things, like uploading files, we get the black "communication failed" error.

The 2 UIs and servlets are much the same, just a different layout. The newer UI is a registration UI and so really only has one form, one view, and is very simple. The other is a full fledged application.

I tried it with asyncSupported = false on my newer application (the Registration UI), but that did not work. I then commented out @WebServlet(urlPatterns = "/Registration/*", name = "WmsRegistrationServlet", asyncSupported = false), so effectively my new UI is not accessible. This did not fix it either.

Since I also changed the web.xml such that I am using 3.0 (web.xml had 2.5 before this), I changed asyncSupport to false for both my UI servlets so it matches the default behavior for 2.5. This also did not fix it.

So then I commented out the Registration WebServlet annotation again and changed @WebServlet(urlPatterns = {"/*", "/VAADIN/*"}, name = "WmsServlet", asyncSupported = false) to @WebServlet(urlPatterns = "/*", name = "WmsServlet", asyncSupported = false) (so got rid of VAADIN reference). This actually fixed things, and now things work like before. So am I handling 2 UI's wrong? Maybe I am dealing with "/VAADIN/*" wrong?


Solution

  • Ok, after reading the documentation multiple times, I finally noticed one minor point they made:

    You do not have to provide the above /VAADIN/* mapping if you serve both the widget sets and (custom and default) themes statically in the /VAADIN directory in the web application. The mapping simply allows serving them dynamically from the Vaadin JAR. Serving them statically is recommended for production environments as it is faster. If you serve the content from within the same web application, you may not have the root pattern /* for the Vaadin servlet, as then all the requests would be mapped to the servlet.

    So once I changed @WebServlet(urlPatterns = {"/*", "/VAADIN/*"}, name = "WmsServlet", asyncSupported = false) to @WebServlet(urlPatterns = "/*", name = "WmsServlet", asyncSupported = true), things worked much better. Since I am not using the VAADIN jar file, but the Vaadin stuff is in my WAR file that gets exploded to a directory (the default setup, as far as I know), it is effectively static, thus this works.

    BTW, I set asyncSupported = true to get around the "A filter or servlet of the current chain does not support asynchronous operations." error (I mention this error here), although, honestly, I am not 100% sure I had to. Since it seems not to be hurting me, I left it as "true".