Notification in Push

Hi, there.

I’m trying to use the push feature in Vaadin 7, and is working ok with components (Label), but I haven’t found a way to make it work with notifications.

My Runnable class is something like this:

    private class MyClass implements Runnable {
        Page page;

        public NotificarMensajes(Page page) {
            this.page = page;
        }

        @Override
        public void run() {
  label.setCaption("New Caption"); //Label inside the view
  label.setIcon(newIcon);
            Notification notification = new Notification("Notification Message"),
Notification.Type.TRAY_NOTIFICATION);
            notification.setPosition(Position.TOP_RIGHT);
            notification.setDelayMsec(10000);
//None of the below methods is working
            notification.show(page); //Page passed in the instantiation
            notification.show(UI.getCurrent().getPage());
            notification.show(Page.getCurrent());
        }
    };

I pass a new instance to the access method of a UI configured to use the push feature according to the instruction shown
here
. The Label label gets updated correctly, but the notification is never shown.

Am I doing something wrong? or is the Notification not supported with Push?

I also tried to update the page title with no success.

page.setTitle("New title");

Maybe I’ve got the wrong page? if so, then how should I get the valid instance?

I’d appreciate any help. Thanks.

Strange. I’m not able to reproduce this - notifications seem to work just fine with push. Could you provide a minimal but complete test application that demonstrates the issue, preferably a single self-contained UI class?

Hi.

Finally I found the problem, I had an error with the instantiation of the Notification object. My actual code was something like this:

Notification notification = new Notification(String.format(
                    "You've got %d new messages.", currentUser.getName(),
                    newMessages), Notification.Type.TRAY_NOTIFICATION);

Where newMessages is an Integer and getName returns a String. Note the error in the string format, where I’m passing a String where should be an Integer. Normally this would lead to a java.util.IllegalFormatConversionException: d != java.lang.String exception, but it seems that the exception is lost inside the Runnable passed to the access method of UI.

In fact, I’ve tested throwing a RuntimeException inside run() in my Runnable and the exception is never shown. I don’t know if this is supposed to work that way, but I’d expected the Exception would be shown somewhere. I really had a bad time trying to find where was my error. BTW I’m using vaadin 7.1.6

It would appear that if you want to get notified of unhandled errors you should use an ErrorHandlingRunnable as your Runnable.

From Ui.access()...

return session.access(new ErrorHandlingRunnable() {
@Override
public void run() {
accessSynchronously(runnable);
}

@Override
public void handleError(Exception exception) {
try {
if (runnable instanceof ErrorHandlingRunnable) {
ErrorHandlingRunnable errorHandlingRunnable = (ErrorHandlingRunnable) runnable;

errorHandlingRunnable.handleError(exception);
} else {
ConnectorErrorEvent errorEvent = new ConnectorErrorEvent(
UI.this, exception);

ErrorHandler errorHandler = com.vaadin.server.ErrorEvent
.findErrorHandler(UI.this);

if (errorHandler == null) {
errorHandler = new DefaultErrorHandler();
}

errorHandler.error(errorEvent);
}
} catch (Exception e) {
getLogger().log(Level.SEVERE, e.getMessage(), e);
}
}
});

Ah, sorry for your debugging woes. The reason for swallowing access() exceptions is that Vaadin internally uses Java FutureTasks to keep track of the access invocations (which can be asynchronous). Now, FutureTask catches all exceptions and stores them in the Future, only to be thrown if Future.get() is called. Fortunately, starting with 7.1.8, Vaadin does call Future.get() for you, and invokes the error handler mechanism if it throws (UI.getErrorHandler() if it’s set and UI.access was called; VaadinSession.getErrorHandler() otherwise). There’s also a “semi-public” interface ErrorHandlingRunnable that you can implement and pass to the access methods to handle errors “inline”.

Oh, thank you very much, I didn’t know about the FutureTask nor the other interface which can be used to handle errors inside runnable. I’ll use that instead, and see how it goes. Thanks!

Note that you have to upgrade to 7.1.8 - in fact, in 7.1.8 your original code would log the exception, instead of swallowing it, without any changes. So this might be a good argument for always using the latest maintenance release available :slight_smile:

The FutureTask stuff is mostly implementation details - the main thing to realize is that the access is done asynchronously, possibly from another thread, so exceptions can’t just propagate normally to the method invoking access(). This is done to avoid some very common deadlock scenarios.

Hi.

For future references, I’d like to point out that Notifications work as expected with Push, the only problem is with error handling inside the Runnable passed to the access method. But, starting with Vaadin 7.1.8, the errors inside Runnable are logged, and don’t get swallowed. The other alternative is to use the ErrorHandlingRunnable interface instead, and log the errors there.

Thanks for the help.