Dass es zuweilen – insbesondere zu Beginn – richtig frustrierend sein kann mit J2EE zu arbeiten wird sicherlich kaum jemanden überraschen.
Momentan verwende ich in einem größeren Projekt – auf Empfehlung von mehreren Freunden – Wicket für den Web Layer und EJB3, mit dem ich inzwischen schon etwas Erfahrung habe, im Business Layer. Komplettiert wird das ganze durch JPA – aber das soll erstmal nichts zur Sache tun.
Nachdem ich vor kurzem die ersten Teile der Anwendung soweit hatte, dass man sie auch als ganzes testen konnte, ist mir aufgefallen, dass sporadisch InvalidClassExceptions geworfen wurden. Zunächst hab ich mir nicht viel dabei gedacht und das Problem ein Weilchen aufgeschoben. Am Anfang konnte ich es auch nur mit abgelaufenen Sessions in Verbindung bringen.
Dummerweise ist es mir dann einige Zeit später auch in einem anderen Zusammenhang passiert – ich hatte einfach nur einen Link angeklickt. Nach kurzem Googlen stieß ich dann auf das Issue WICKET-2416, was ziemlich genau das Verhalten meiner Anwendung beschrieb. Einen Link anklicken, die Browser Back-Funktion verwenden, einem weiteren Link folgen und schon trat die Exception auf.
Wicket verwaltet für jede Seite ein Objekt, welches serialisiert wird um einen Zustand über mehrere Requests hinweg aufrecht zu erhalten – beim Deserialisieren eines Seitenobjekts mit einer EJB-Referenz trat der Fehler auf.
Das genannte Issue interpretierte ich nun zuerst so, dass Glassfish, der von mir verwendete Application Server, unterschiedliche Classloader für den EJB und den Web Layer verwendet und Klassen, die mit dem EJB Loader geladen wurden für den Web Layer nicht sichtbar sind, selbst wenn sie Teil des gleichen EAR sind – das, was ich vorhatte wäre also völlig unmöglich.
Das brachte mir einen Tag mit wenig Produktivität und viel Verzweiflung ein, an dem ich mich schon darauf einstellte auf JBoss zu wechseln.
Nachdem ich die Sache dann überschlafen hatte widmete ich mich heute morgen erneut dem Problem – so leicht wollte ich die bisherige Arbeit, die ansonsten auch wunderbar funktionierte, nun doch nicht aufgeben.
Die Lösung auf die ich nach ausgiebigem Googlen dann kam war dann leider auch relativ simpel: Es ist völlig normal, dass die Klassen aus dem EJB Modul nicht sichtbar sind – und eigentlich auch überhaupt nicht Wicket-spezifisch. Deshalb benötigt das Web Modul eine Klassenbibliothek mit den Bean Interfaces und Entities.
Nachdem ich eine solche erstellt und eingebunden hatte war ich die Exception los – mit ein paar Änderungen im ant Script war die Sache auch relativ schnell automatisiert.
Der Eröffner des erwähnten Issues kam auf das Problem wohl nur aus dem Grund, dass er Wicket als domänenweite Bibliothek in Glassfish hinzugefügt hatte (die wohl wiederum mit einem dritten Classloader geladen wird?).
Ein paar Fragen bleiben aber:
Wenn die Klassen generell nicht sichtbar sind – warum funktionierte denn der ursprüngliche Lookup überhaupt? Die Exception trat nur bei der Deserialisierung auf.
Außerdem erstellt NetBeans standardmäßig eine .jar für das EJB Modul, die es dem Web Modul als Abhängigkeit hinzufügt und auch mit ihm packaged – auf den ersten Blick sah es für mich auch so aus als ob diese alle nötigen Klassen bereits enthält.
Etwas Verwirrung bleibt – vielleicht klärt mich ja jemand auf, aber wie dem auch sei bin ich nun erstmal zufrieden dass es funktioniert 😉