Customizing system messages

I thought that I could just create new SystemMessagesProvider:

public class MySystemMessagesProvider implements SystemMessagesProvider {

    @Override
    public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) {
        CustomizedSystemMessages messages = new CustomizedSystemMessages();
        messages.setInternalErrorCaption("internal error");

        messages.setSessionExpiredCaption("session expired");

        messages.setOutOfSyncCaption("out of sync");

        messages.setCommunicationErrorCaption("communication error");

        messages.setCookiesDisabledCaption("cookies disabled");

        messages.setAuthenticationErrorCaption("authentication error");
        return messages;
    }
}

And then just set it to VaadinService:

public class MyVaadinUI extends UI {

    @Override
    protected void init(VaadinRequest request) {

        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);

        Button btn = new Button("Turn off the server and click me.");
        layout.addComponent(btn);

        VaadinService.getCurrent().setSystemMessagesProvider(new MySystemMessagesProvider());
    }
}

When I turn off the application server then I expect communication error should be shown with “communication error” caption. But this doesn’t work and it seems that setting system messages provider should be done elsewhere.

Does anyone know more about that?

I just found that: in case I click on the button and then I switch off the server (and then I click on the button again), the customized message is shown. In case I don’t click on the button and I just switch off the server (and then I click on the button again), the default message is shown.

I’m using Vaadin 7.0.0
And I have the same problem, but I don’t even get my customized message, I always get the default one…

It looks like a bug…Or is there something else to set or implements ?

update : In my case I used the new way to define system Message with a setSystemMessagesProvider :

      VaadinService.getCurrent().setSystemMessagesProvider(new SystemMessagesProvider() {
			
			@Override
			public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) {
			    CustomizedSystemMessages messages = new CustomizedSystemMessages();
			    messages.setCommunicationErrorCaption("Serveur Out ?");
			    messages.setCommunicationErrorMessage("The server is not responding anymore, please check again later...");
			    messages.setCommunicationErrorNotificationEnabled(true);
			    messages.setCommunicationErrorURL("about:blank");
			    return messages;
			}
		}); 

Never tried it, but I would think, that you need to set the SystemMessagesProvider BEFORE the Vaadin-App actually starts as the error-messages will be needed both on client- and on server-side. So using a SessionInitListener might be a good shot. There is also an example in the wiki, although that one corresponds to BootstrapListeners if I remember correctly.

And where do you set this SessionInitListener?
In the init method of the main UI class? That make no sense since it is there that I set the SystemMessagesProvider…

Hello.

I have the same problem. I’m doing it in the same way (using VadinService.getCurrent().setSystemMessagesProvider(new SystemMessagesProvider…), but I still get the default messages.
And “overriding” the static getSystemMessages() in my UI class doesn’t work neither. It seems that this method is never called.

This is how it works: As pointed out earlier, the error-messages need to be available as well on client as on server-side in order to have be usable when for example the connection has been lost. Therefore they must be rendered into the wrapping HTML-page. As that HTML-page is rendered before the actual Vaadin-UI gets executed, you need to set the SystemMessagesProvider outside your UI’s methods.

Servlet:

package de.tobiasdemuth.vaadin7test.customsystemmessagetest;

import javax.servlet.ServletException;

import com.vaadin.server.CustomizedSystemMessages;
import com.vaadin.server.ServiceException;
import com.vaadin.server.SessionInitEvent;
import com.vaadin.server.SessionInitListener;
import com.vaadin.server.SystemMessages;
import com.vaadin.server.SystemMessagesInfo;
import com.vaadin.server.SystemMessagesProvider;
import com.vaadin.server.VaadinServlet;

public class CSMTestServlet extends VaadinServlet {
	
	private static class MySystemMessagesProvider implements SystemMessagesProvider {

		@Override
		public SystemMessages getSystemMessages(
				SystemMessagesInfo systemMessagesInfo) {
			CustomizedSystemMessages messages = new CustomizedSystemMessages();
	        
			messages.setInternalErrorCaption("BÄM - internal error");
	        messages.setSessionExpiredCaption("BÄM - session expired");
	        messages.setOutOfSyncCaption("BÄM - out of sync");
	        messages.setCommunicationErrorCaption("BÄM - communication error");
	        messages.setCookiesDisabledCaption("BÄM - cookies disabled");
	        messages.setAuthenticationErrorCaption("BÄM - authentication error");
	        
	        return messages;
		}
		
	}

	@Override
	public void servletInitialized() throws ServletException {
		super.servletInitialized();
		
		getService().addSessionInitListener(new SessionInitListener() {

			public void sessionInit(SessionInitEvent event)
					throws ServiceException {
				event.getService().setSystemMessagesProvider(new MySystemMessagesProvider());
			}
			
		});
	}

}

UI:

package de.tobiasdemuth.vaadin7test.customsystemmessagetest;

import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.*;

public class CSMTestUI extends UI {
	
	@Override
	public void init(VaadinRequest request) {
		Button b = new Button("Press me after shutting down the server!");
		setContent(b);
	}

}

Wiring in web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	
	<display-name>CustomSystemMessageTest</display-name>
	
	<context-param>
		<param-name>productionMode</param-name>
		<param-value>false</param-value>
	</context-param>
	
	<servlet>
		<servlet-name>CSMTestUI</servlet-name>
		<servlet-class>de.tobiasdemuth.vaadin7test.customsystemmessagetest.CSMTestServlet</servlet-class>
		<init-param>
			<param-name>UI</param-name>
			<param-value>de.tobiasdemuth.vaadin7test.customsystemmessagetest.CSMTestUI</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>CSMTestUI</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
	
</web-app>

Tobias, thanks for the answer. When I have time I will try it.

It works! :slight_smile: Thank you very much.

Tobias, I played with your example and work quite nicely, but I figured out that the message have tree parts, a caption, a message and a detail. There is api to translate the caption and message, but I not found for the details.

Do you know how to translate the details or turn it invisible?

I don’t think there is a way to localize or hide the details as those are technical information about the error like last received JSON or stacktraces etc …

Ok, but what about setting SystemMessageProvider when using Vaadin 7 and portlets (i.e. in liferay) ? The documentation says nothing more than “to be done”.

I set my custom message with this:

VaadinService.getCurrent().setSystemMessagesProvider(new MySystemMessagesProvider());

and set the timeout with this:

VaadinSession.getCurrent().getSession().setMaxInactiveInterval(timeout);

When “timeout” is a short time, like 20 seconds, my custom message show correctly, but, when “timeout” is a long time, like 5 minutes, the message is the default, it’s not my custom message. I don’t understand why!

Someone can tell me why?

I have te same problem. I dont know, is probably a Bug. Try with odler vaadin version.

Tried it only with OSGI servlet declaration and it does not work. It’s not working no matter what I do :frowning:

I work with version 7.7.6 and I have the same problem like Таня Иванова.

It worked for me like this: https://gist.github.com/vonloxley/4143c8fa0c3f0124787399bd086ba1a4

Works!!! Thank you kmh!!! :smiley:

In Vaadin 8 you can use VaadinServiceInitListener:

import com.vaadin.server.ServiceInitEvent; 
import com.vaadin.server.VaadinServiceInitListener; 

public class VaadinServiceListener implements VaadinServiceInitListener { 

   @Override public void serviceInit(ServiceInitEvent event) { 
      event.getSource() .setSystemMessagesProvider(new VaadinSystemMessageProvider()); 
   } 
}

You must remeber add your listener to META-INF/services/com.vaadin.server.VaadinServiceInitListener, from documentation:

Listener instances are by default discovered and instantiated using ServiceLoader.
This means that all implementations must have a zero-argument constructor
and the fully qualified name of the implementation class must be listed on a separate line in a
META-INF/services/com.vaadin.server.VaadinServiceInitListener
file present in the jar file containing the implementation class.

Thanks for this hint, got it running under Vaadin 7.7.12.
I actually have to mention that in my specific project, with had been created from Vaadin archetype “vaadin-archetype-application-multimodule”, the UIServlet existed as an inner class of the UI class. I such had to make it a regular class first before I could address it in web.xml like “com.ssg.fcp.fcp_e761.fcpUIServlet” as explained in “Wiring in web.xml” post of Tobias Demuth.