Search code examples
vaadin7

Vaadin 7 - Notification Messages Fail to Render


I am upgrading my Vaadin 6 application to Vaadin 7 and things are going pretty well in general. I am running under JBoss AS 7.3.2.

However, I am converting all of my notifications from :

getWindow().showNotification("Under Vaadin 6 this works just fine");

to

Notification.show("Under Vaadin 7 this does not work for me");

and the none of the messages render in the browser. They do not show up in the browser. At all. On Firefox, Chrome and IE. The Vaadin 6 to 7 migration guide addresses this in one sentence:

The API for Notifications has also changed, static methods Notification.show() are 
now used instead of Window.showNotification()

so I assumed that changing that one line of code is all I needed to do. Maven dependencies went from this:

<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin</artifactId>
  <version>6.8.14</version>
</dependency>

to this:

<properties>
  <vaadin.version>7.3.6</vaadin.version>
</properties>
. . .
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-server</artifactId>
        <version>${vaadin.version}</version>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-client-compiled</artifactId>
        <version>${vaadin.version}</version>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-client</artifactId>
        <version>${vaadin.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-push</artifactId>
        <version>${vaadin.version}</version>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-themes</artifactId>
        <version>${vaadin.version}</version>
    </dependency>

But the messages do not render in the browser.

UPDATE: I can get the Notification to show up, but only if I manually refresh the browser window (after I make sure @PreserveOnRefresh is set in my UI subclass). This is because the Notification is added to a List of Notifications inside the Page object, and rendered to the browser when paintContent() is called. Unfortunately, the only way I have gotten paintContent() to be called thus far is to manually refresh the browser window.

With Vaadin 6.x I saw the message in the browser. With Vaadin 7.3.6 I see nothing. The message simply fails to render. My application works fine (I also use log4j to log each message that is supposed to be displayed to the user, so I can tell my code paths are still solid). The user messages simply do not show up.

Thinking maybe there is some sort of error under the covers, I installed a DefaultErrorHandler in my UI class and see no output (like many frameworks Vaadin eats exceptions, but the ErrorHandler is supposed to bring them to light).

I tried adding ?debug to the end of my URL to see if additional information showed up that way. Still nothing.

From the lack of posts on this topic, it would appear that I am the only one having this issue. I hope that is not the case, thus I appeal to the forum for help.

If you have migrated from 6 to 7 and have seen issues like this one, your help would be much appreciated. If you have not, please don't bother. I have tried all the obvious stuff.

If you would like to see source code, it is above.


Solution

  • The short answer to this is NEVER EVER (EVER) do this in your UI subclass:

    @Override
    public void markAsDirty() {
      // Empty body (except for this comment)
    }
    

    "But, Steve, why not?" you ask. Well, this method lets the Vaadin framework know that there are unrendered changes that occurred during the normal request/response cycle that need to be rendered back to the browser upon return.

    Overriding this method with an empty method body short circuits the "dirty" check and the Notification is not rendered back to the browser in the response in which you expect it. It's still sitting there, though, and if your UI subclass is marked @PreserveOnRefresh you will see the notification on the next response (which occurs if you refresh the browser Window, as I discovered).

    If you need to override markAsDirty() for some reason, for heaven's sake do this:

    @Override
    public void markAsDirty() {
      super.markAsDirty();// VERY IMPORTANT
    }
    

    In the course of research and code changes, I do not exactly recall when I decided to override this method in my UI subclass with an empty method body. But I do know this: overriding markAsDirty() with an empty method body was the source of this problem.

    I'm not sure if this was such a mind-numbingly stupid thing to do (probably) that I should keep quiet, or if I should warn others. In the interest of caution, and for completeness (and closure) I decided to humbly confess and post this answer as a cautionary tale.

    If you insist on commenting, please be kind, for Karma often has her way, and one day you will be the idiot.

    JSP