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.
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…
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);
}
}
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”.
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!
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.