Factory already available for this class loader

In einem JSF-Projekt habe ich einen SessionExpired-Filter eingebaut. Der Filter implementiert das javax.servlet.Filter Interface und leitet den Benutzer auf die Login-Seite um, wenn die Session abgelaufen ist. Der Filter hat an sich super funktioniert, bis ich wieder einen Stresstest mit jMeter gemacht habe. Dabei ist im Filter folgende Exception geworfen worden:

java.lang.IllegalStateException: Factory already available for this class loader.

Ich habe den Fehler zuerst in meinem Filter gesucht, der zweite Uebeltaeter den ich in Verdacht zog war Tomcat. Doch tatsachlich war es wieder einmal die JSF Komponenten Libary ADF/Trinidad.

http://www.mail-archive.com/adffaces-issues@incubator.apache.org/msg02333.html

Wenn nach einem Serverstart zwei Threads gleichzeitig auf die Applikation zugreifen kommt der Dispatcher durcheinander.
Ganz grosses Kino!!!

Multiple MessageBundles in JSF ManagedBeans

In einer bestehenden Web-Applikation, mit MyFaces 1.1.5 wollte ich aus einer MessageBean auf verschiedene MessageBundles zugreifen. Die betroffene Klasse erbt von der BaseBean, welche folgende Methode zur Verfügung stellt:

public String getStringFromResourceBundle(final String key) {
    return ResourceBundle.getBundle(getApplication().getMessageBundle()).getString(key);
}

Die faces-config habe ich um zwei weitere ResourceBundles erweitert.

<application>
 <default-render-kit-id>org.apache.myfaces.trinidad.core</default-render-kit-id>
 <variable-resolver>
     org.springframework.web.jsf.DelegatingVariableResolver
 </variable-resolver>
 <locale-config>
     <default-locale>de</default-locale>
 </locale-config>
 <message-bundle>
     de.itservices.onlineservices.resources.gui.status
 </message-bundle>
 <message-bundle>
     de.itservices.onlineservices.resources.gui.buildno
 </message-bundle>
 <message-bundle>
     de.itservices.onlineservices.resources.gui.messages
 </message-bundle>
</application>

In der betroffenen Klasse habe ich über die Methode aus der BaseBean eine Property aufgerufen dien in der status.properties hinterlegt ist. Der Aufruf endete in einer MissingResourceException.

java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key Revision

Wenn mehrere message-bundles in der faces-config eingetragen sind, wird in der Implementierung von MyFaces 1.1.5 der letzte Eintrage genommen. Properties aus den ersten beiden message-bundles stehen nicht zur Verfügung.
Soll in einer ManagedBean auf mehr als auf eine message-bundle/Properties zugegriffen werden, muss der Zugriff erst implementiert werden. Hier eine mögliche Lösung.

URL url = this.getClass().getClassLoader().getResource("de/firma/projekt/resources/buildno.properties");
String path = url.getPath().replaceAll("%20", " ");
Properties prop = new Properties();
prop.load(new FileInputStream(path));
String zeit = prop.getProperty("Time");

Die zweite Zeile ist ein Workaround für Pfade mit Leerzeichen auf Windows-Systemen, aber das ist ein anderes Thema.
Ich habe mir die JSF 1.2 Spezifikation heruntergeladen und dannach durchsucht. Die Spez. ist zu diesem Thema nicht transparent, sie sagt nichts darüber aus, was geschehen soll wenn mehrere message-bundles in der faces-config.xml eingetragen sind und aus einer ManagedBean versucht wird darauf zuzugreifen. Es waere natuerlich schoen wenn die Methode getApplication().getMessageBundle() einen MessageBundle zurueckgeben wuerde der die Properties aus allen MessageBundles enthaelt die in der faces-config.xml eingetragen sind.