How to remove the surrounding ??? when message is not found in bundle

The basename can point to a fullworthy ResourceBundle class. E.g.

<f:loadBundle basename="resources.Text" var="msg" />

with

package resources;

public class Text extends ResourceBundle {

    public Text() {
        setParent(getBundle("resources.text", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
    }

    @Override
    public Enumeration<String> getKeys() {
        return parent.getKeys();
    }

    @Override
    protected Object handleGetObject(String key) {
        return parent.getObject(key);
    }

}

You can overridde the bundle message handling in handleGetObject. JSF by default (by spec) calls getObject(), catches MissingResourceException and returns "???" + key + "???" when caught. You can do it differently.

@Override
protected Object handleGetObject(String key) {
    try {
        return parent.getObject(key);
    } catch (MissingResourceException e) {
        return key;
    }
}