Bug oder Feature in Java 6?

Die Tage ist ein interessantes Problem zu Java 6 aufgetreten zudem es sich lohnt die Lösung zu notieren sonst sucht man in zwei Wochen wieder danach..

Ziel war es ein simples kleines JSF 1.2 Projekt in Eclipse WTP aufzusetzen welches von Eclipse heraus auf den Tomcat 6 deployt und ausgeführt wird. Das ganze sollte unter Java 6 auf eine MS Windows System laufen. Dabei wurde im ersten Schritt lediglich das leere initiale Projekt verwendet bei dem im Verzeichnis WEB-INF/lib schon sämtliche Bibliotheken lagen – mehr war noch nicht vorhanden. Man sollte annehmen, dass sich das Projekt ohne Probleme deployen lassen sollte allerdings ist beim Starten des des Tomcats diese Log Ausgabe in der Konsole zu lesen gewesen:

com.sun.faces.config.ConfigureListener contextInitialized
INFO: Completed initializing Sun’s JavaServer Faces implementation (1.2-b20-FCS) for
context ‘/TestDWP’
org.apache.catalina.core.StandardContext listenerStart
SCHWERWIEGEND: Exception sending context initialized event to listener
instance of class com.sun.faces.config.GlassFishConfigureListener

Mit folgender ClassNotFoundException Exception:

javax.faces.FacesException: java.lang.ClassNotFoundException:
[Ljava.lang.String;
       at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:535)
       at com.sun.faces.config.GlassFishConfigureListener.contextInitialized(GlassFishConfigureListener.java:47)
       ...
Caused by: java.lang.ClassNotFoundException: [Ljava.lang.String;
       at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1360)
       at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1206)
       ... 16 more

Der interessante Teil an der Exception ist "Caused by: java.lang.ClassNotFoundException: [Ljava.lang.String;", welcher nicht erklärbar scheint.
Die Lösung bzw. Workaround dafür schon einmal vorab. Der JRE 6 bzw JDK 6 als VM Argument folgendes mitgeben: -Dsun.lang.ClassLoader.allowArraySyntax=true
Ist dieses Argument gesetzt tritt die Exception nicht mehr auf.

In einem Forum habe ich dann den Hinweis auf einen Bug Report bei Sun gefunden der dieses Verhalten beschreibt und folgendes Beispiel zum reproduzieren des Bugs auflistet:

public class test {
    public static void main(String[] args) throws Exception {
        String[] s = new String[] { "123" };
        String clName = s.getClass().getName();
        test.class.getClassLoader().loadClass(clName);
    }
}

Mit Java 5 (1.5) läuft dieser Code wunderbar aber mit Java 6.0 erhält man eben diese ominöse ClassNotFoundException Exception:

Exception in thread "main" java.lang.ClassNotFoundException: [Ljava.lang.String;
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at test.main(test.java:7)

Obwohl in der Bugbeschreibung bei Sun der State auf "3-Accepted" steht streitet man sich ein wenig darüber ob das nun wirklich ein Bug ist. Eine offizielle Aussage von Sun selbst ist dort jedenfalls noch nicht vermerkt.
Fest steht, dass Sun etwas in dem Verhalten des Classloaders in Java 6.0 verändert hat und diese Veränderung sich auf manche Bibliotheken fatal auswirkt. Von daher kann diese kleine Notiz hier doch nützlich sein :).

[Update]
Jetzt hatte ich den gleichen Fall auch noch einmal bei dem Aufsetzen einer Testumgebung mit JBoss Seam, Embeddeble JBoss und TestNG bei der folgende, ein wenig von der oben gelisteten abweichende, Exception aufgetreten ist:

Caused by: java.lang.ClassNotFoundException: [Ljava.lang.Class;
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)

Hier heißt der interessante Satz "Caused by: java.lang.ClassNotFoundException: [Ljava.lang.Class;". Auch diese in Java 6.0 aufgetretene Exception konnte durch das oben genannte JVM Paramter gelöst werden.

In Eclipse kann man man die VM Angabe unter den Installed JREs (Hauptmenü->Window->Preferences->Java->Installed JREs) konfigurieren. Dazu die konfigurierte JRE/JDK 6.0 zum editieren öffnen und die VM Angabe "-Dsun.lang.ClassLoader.allowArraySyntax=true" in der Zeile "Default VM Arguments" angeben.

Tags:

Wenn du Fragen oder Anregungen zum Post hast, dann hinterlasse doch einen Kommentar oder wenn du weiterhin Artikel von Javathreads lesen möchtest, dann abonniere den RSS Feed und sehe direkt in deinem Feed Reader die nächsten Artikel.

Ähnliche Artikel, die dich interessieren könnten:
    None Found
Kommentare

Danke für den Artikel! hatte das mit JBoss Seam und TestNG und ohne deinen Artikel wär ich wohl nie auf ne Lösung gekommen.

Ich benutze 1.6.0 unter OSX 10.5.5, was hast du für ne Umgebung? Wundert mich, dass das nur selten (zumindest laut google) auftritt.

Hi Niko,
ich hatte das Problem unter Windows XP und Linux (Debian), soweit ich mich erinnern kann.

Bei mir ist es beides mal unter der Verwendung von JSF aufgetreten einmal bei dem Wechseln von MyFaces 1.2 auf JSF RI 1.2 (oder umgekehrt – weiß nich mehr ;) und einmal wie bei dir bei Seam und TestNG.

Habe für das Lösen dieses Problems (beim ersten mal) auch etwas länger gebraucht und beim zweiten Auftreten beschlossen es hier zu posten – hat ja was genutzt =).

Hi,

super. Vielen Dank für die Lösung. Das Problem existiert immernoch… :-(((

Hinterlasse einen Kommentar