corner
Home      Know How         Guidelines      Top J2EE Fehler

Top 10 Fehler beim Einsatz von J2EE

Java, EJBs und J2EE sind keine neuen Technologien mehr. Durch ihrer Komplexität sorgen sie dennoch dafür, dass altbekannte Fehler wiederholt werden.

Die Fehler sind in 2 Kategorien aufgeteilt: Architektur- und Projektfehler. Einige der aufgelisteten Punkte sind nicht unbedingt J2EE spezifisch und daher allgemein gültig. Die Erklärung baut immer auf die speziellen Eigenarten von EJBs und J2EE auf.

Die folgende Liste erhebt keinen Anspruch auf Vollständigkeit, sondern bietet einen Erfahrungsüberblick aus zahllosen J2EE Projekten. Sie ist daher nicht als allgemeine Anleitung zum Aufbau von J2EE Anwendungen zu verstehen.

J2EE Architekturfehler

1. Alles ist eine EJB

Sobald die grundlegende Arbeitsweise von EJBs vom Entwickler verstanden wird, verfällt er oft in dem Vorgehen, alles als eine Session Bean oder Entity Bean zu implementieren. Das ist ein großer Irrtum, denn EJBs sind kein grundsätzliches Implementierungsparadigma, sondern eine Framework zur Remotekommunikation und Verteilung von Komponenten. Wird dieses Framework überstrapaziert sind die Folgen meist ein unübersichtliches Design und schlechte Performance. Der überwiegende Teil eines Systems sollte daher aus klassischen POJOs (Plain Old Java Objects) bestehen.

2. Kein vernünftiges Schichtenmodell

Die gute Strukturierung von Software ist ein grundsätzliches Problem, das nicht nur in der J2EE Welt vernachlässigt wird. Eine minderwertige Strukturierung bedeutet einen hohen Entwicklungsaufwand und schlechte Wartbarkeit. Typischerweise werden im J2EE - Bereich folgende Fehler gemacht:

  • Keine Trennung zwischen Präsentationsschicht und Businesslogic. Beispiele hierfür sind mit Java-Code überfrachtete JSP Seiten sowie das Servlet, in der die ganze Anwendungslogik implementiert wird.
  • Keine genaue Festlegung, welche Schicht remote aufrufbar ist, und welche nicht.

3. Feingranulare Remoteaufrufe

Verteilte Anwendungen leiden oft unter folgenden Problemen:

  • Die Kosten für einen Remoteaufruf werden unterschätzt
  • Es ist dem Entwickler nicht klar, was alles einen Remoteaufruf verursacht

In der J2EE-Welt kommt es daher meist zu folgenden Fehlern:

  • Es existiert kein Business-Delegate, der die Koordination von EJBs für einen Client übernimmt.
  • Entity Beans werden direkt vom Client verwendet
  • Heterogene EJB-Verteilung auf unterschiedlichen Rechners eines Clusters.

4. Verletzung des Parallelitätsprinzips

EJBs sind dafür gedacht, dass sie von vielen Benutzern gleichzeitig verwendet werden. Meist bedeutet das, dass der Application Server viele EJB Instanzen und viele Threads verwalten muss. Daraus schöpft eine J2EE Anwendung Ihre Kraft, denn (quasi-)parallel laufende Objekte können vom Betriebsystem gut auf vorhandene CPU-Zeit verteilt werden.

Dies bedeutet, dass Singletons und synchronisierte Komponenten für J2EE Anwendungen mit großer Vorsicht zu verwenden sind: Alle parallel arbeitenden Benutzer müssen durch dieses Nadelöhr. Benötigt diese Komponente viel Zeit, warten währenddessen alle Anderen. Wie viel Zeit eine Komponente tatsächlich benötigt, lässt sich in der Regel nur mit einem realistischen Lasttest genau feststellen.

5. Langläufige Requests und Transaktionen

Klassische J2EE Anwendungen arbeiten mit einem synchronen Aufrufmodell: Eine Benutzeranfrage erreicht das System und der Benutzer wartet so lange, bis das Ergebnis der Anfrage zurückgeliefert wird. Dieses Modell funktioniert sehr gut, solange man sich in der Entwicklungsphase befindet und nicht mehr als ein Benutzer (der Entwickler) mit der Anwendung arbeitet. Problematisch wird es, sobald das System unter Last steht, und man nicht genügend darauf geachtet hat, dass Prozesse und deren Transaktionen kurzlebig sind. Die Folge: Durch Timeouts ist praktisch kein Benutzer mehr in der Lage irgend etwas zu tun.

Für dieses Problem gibt es viele mögliche Lösungen: Optimierung der langläufigen Transaktionen, Beschränkung der gleichzeitig laufenden Prozesse, asynchrone Entkopplung der Komponenten (z.B. durch JMS). Wichtig dabei ist, so früh wie möglich potentielle Langläufer zu identifizieren. Die Anpassung der Architektur ist dann meist problemlos möglich.

J2EE Projektfehler

1. Kein ausreichendes Architekturdesign durchgeführt

J2EE unterstützt die Anwendungsentwicklung in vielen Bereichen und bringt eine ganze Reihe von Modelllösungen mit. Dies verleitet zu der Ansicht, dass ein Design nicht mehr nötig ist: J2EE wird als bereits fertige Architektur interpretiert. Im Grunde genommen ist es genau umgekehrt, denn die Vielfalt an Möglichkeiten und Techniken bedürfen einer ausgewogenen Auswahl und Orchestrierung.

Der gedankenlose Einsatz von J2EE-Komponenten (EJBs, JSPs, Servlets, JMS, Security, ...) führt zu einem chaotischem System, in dem sich nach kurzer Zeit niemand mehr auskennt.

2. J2EE Technologie nicht kennen

Der Umgang mit einer komplexen Technologie kann nicht "on the flight" zur Projektzeit erlernt werden. Das gilt insbesondere für J2EE, welches, wie bereits erwähnt, viele Modelllösungen mitbringt. Wird das vorgegebene Modell nicht verstanden, hat das schwerwiegende Folgen auf die entstehende Anwendung.

Sicherlich müssen nicht alle Projektmitglieder J2EE Gurus sein, doch der Technologiehintergrund muss allgemein bekannt sein.

3. Toolmania

Frei nach dem Motto "viel hilft viel" wird die Entwicklungsumgebung in J2EE-Projekten mit Tools überfrachtet. Dabei wird schnell vergessen, dass jedes Tools meist eine nicht unerhebliche Einarbeitungszeit erfordert. Auch ist kein Tool fehlerfrei. Im günstigsten Fall kann man diese umgehen, im schlechtesten wird der Entwicklungsprozess massiv gestört.

Ein Alarmsignal für den schlechten Einsatz von Tools ist, dass die Entwickler nicht mehr zu dem kommen, was Sie eigentlich machen sollen: programmieren. Stattdessen wird ein nicht unerheblicher Teil der Zeit für die Handhabung und Konfiguration der Tools beansprucht.

4. Entwicklungs- und Laufzeitsystem unterschiedlich

Vor dem Aufkommen von Java, war es eine Selbstverständlichkeit, dass Entwicklungs- und Laufzeitsystem gleich waren. Betriebssysteme und Programmiersprachen waren für nichts anderes ausgelegt. Java hat diese Notwendigkeit zwar geändert, aber nicht vollkommen eliminiert.

Es bestehen weiterhin große Unterschiede zwischen Java-Umgebungen auf verschiedenen Betriebssystemen. Dies hat meist damit zu tun, wie low-level Resourcen implementiert sind. Prominente Beispiele hierfür sind Threads, I/O und Bildschirmausgabe (AWT). Nicht alle Unterschiede werden von Java gekapselt, und können daher zu unvorhergesehenem Anwendungsverhalten führen.

5. Keine oder mangelhafte Performance- und Sizinganalyse

In kaum einem J2EE Projekt macht man sich Gedanken darüber, welche realistische Last das Produktivsystem bewältigen muss. Oft werden nur primitive Lasttests gefahren, die in keinster Weise das tatsächliche Benutzerverhalten nachbilden. Geschieht das dennoch, dann wird der logisch nächste Schritt nicht mehr vollzogen: Die Berechnung der nötigen Hardwareresourcen. Typischerweise wird irgend eine Maschine gekauft, von der man einfach glaubt, dass sie gut dimensioniert ist und noch gut ins Budget passt.

Die Konsequenz daraus ist, dass erst mit dem Produktivstart die benötigte Systemleistung ermittelt wird. Was folgt ist die hektische Suche nach Engpässen in der Architektur und im Programmcode.

Wolfgang Schaub
2004-02-03
Kontakt/Impressum    Über Iternum    Rechtliche Hinweise    Datenschutz   © iternum GmbH 2008