Schneller, höher, weiter! Das Entwickeln von JEE-Applikationen ist bestimmt durch Round-Trips aus Code-Änderung, Kompilierung, Re-Deployen und Testen. Da sich diese Round-Trips in kurzen Abständen (Minutenbereich) wiederholen, sollte das Kompilieren und Re-Deployen so wenig Zeit möglich in Anspruch nehmen. Zum einen lässt das schlicht mehr Zeit zum Programmieren und Testen. Zum anderen macht das Arbeiten den Programmierern so einfach mehr Spaß! (… und die Zufriedenheit des Programmierers ist direkt proportional zur Lebensdauer seiner Tastatur).
Durch zeitgesteuerte Aktionen kann ein Softwaresysteme bestimmte Anforderungen umsetzen. Zum Beispiel könnte eine Anforderung sein, dass eine Applikation jede Nacht bestimmte Datenbereinigungen durchführt. Bei OpenWishes prüfen wir beispielsweise periodisch, ob Geburtstagserinnerungen per E-Mail versendet werden müssen. Dies sind natürlich nur triviale Beispiele. Der Faktor Zeit kann nicht nur Aktionen auslösen, sondern auch das Verhalten von Geschäftslogik beeinflußen. Beispielsweise kann der Kunde im Support-Portal nach Ablauf der Garantiezeit eines gekauften Artikels keinen Reklamationsvorgang mehr einleiten.
Überaschenderweise finden Java Applets auch heute noch immer wieder ihre Nische in Systemlandschaften. Wenn es darum geht, aus einer Web-Anwendung heraus eine Schnittstelle zum lokalen System des Anwenders zu etablieren, sind Applets keine schlechte Wahl. Über die HTML-Seite in welche das Applet eingebunden ist, können Parameter an das Applet übergeben werden. Ebenso ist die bidirektionale Kommunikation zwischen Applet und Javascript möglich (siehe Netscape Live Connect). Ein signiertes Applet erlaubt es, lokale Dateien zu lesen und zu schreiben. Ebenso kann ein signiertes Applet mit entfernten Servern kommunizieren, obwohl es nicht von diesen geladen wurde.
Diese Möglichkeiten sind der Grund für den Einsatz von Applets in meinem aktuellen Projekt in München. Bei einem großen deutschen Automobilhersteller sind Applets ein (sehr kleiner) Teil derSystemlandschaft zum Produktdatenmanagement. Das nur am Rande.
Unter dem Strich erlauben wir dem Anwender mittels eines Applets Dateien zu und vom Server zu laden. Es handelt sich dabei um Office-Dokumente, Messergebnisdaten und CAD-Dateien. Die Dateien können also recht groß – gar bis über einem Gigabyte groß – sein.
Speicherproblem beim Versenden großer Datenmengen über HTTP
Die Übertragung der Dateien zum Server ist unter Verwendung der JDK-Klasse HttpURLConnection realisiert. Bei sehr großen Dateien wurde auffällig, dass die JVM sehr viel Speicher allokiert und irgendwann mit einen OutOfMemoryError die Ausführung des Applets das zeitliche segnet. Die Ursache war schnell gefunden: Die HttpURLConnection puffert sämtliche in einem HTTP-Post-Request zu übermittelnden Daten um die Anzahl der zu sendenden Bytes zu ermitteln. Diese Angabe muss die Implementierung von HttpURLConnection im Request-Header-Feld “content-length” übermitteln. Der Header muss vor den Nutzdaten beim HTTP-POST-Request gesendet werden. Die zu sendende Datei wird zwar mittels InputStream gelesen und direkt in den OutputStream von HttpURLConnection geschrieben, aber HttpURLConnection puffert die gesamte Datei im Hauptspeicher bevor auch nur ein Byte an den Ziel-HTTP-Server gesendet wird. Dies führt natürlich unweigerlich zu Problemen. Leider bietet die API von HttpURLConnection keine Möglichkeit die Content-Length zu setzen, so dass die zu versendenden Daten nicht gepuffert werden.
Eine nicht funktionale Anforderung an Software-Systeme wird gemeinhin mit dem Begriff “Security” umrissen. Ein Teilaspekt betrifft die Authorisierung von Benutzern / Fremdsystemen gegenüber bestimmten Diensten oder Daten. Bei mehrschichtigen Softwaresystemen, die eine Datenbank in der Ressourcenschicht einbinden, ist die Authorisierung oft Aufgabe der Geschäftsschicht.
Ein anderer Ansatz stellt die Realisierung der Authorisierung direkt in der Datenbank dar. Diesen Ansatz findet man oft in Alt-Systemen, bei denen zumal auch Geschäftslogik in der Datenbank in Form von Stored Procedures umgesetzt ist. Damit die Datenbank Authorisierungsfunktionen übernehmen kann, muss der tatsächliche Benutzer an die DB propagiert werden.
| |
Im Rahmen dieses Artikels möchte ich ein wenig Know-How für die Implementierung dieses Ansatzes in Verbindung mit dem Oracle-DBMS (Datenbankmanagementsystem), Connection Pooling im Weblogic Application Server und JDBC weitergeben. Dieses Know-How entstammt der Anbindung einer Produktdatenbank bei einem großen Deutschen Automobilhersteller. Zum Einsatz kommt eine proprietäres Feature des Oracle-DBMS – die Oracle-Proxy-Sessions.
Moderne Web-Anwendungen setzen Ajax ein um die Usability zu verbessern – das weiß doch jedes Kind! Eine tolle Sache zur Verbesserung der Usability ist es, für kurze Benutzerinteraktionen einen Popup-Dialog einzublenden, der vom Benutzer einfach wieder geschlossen werden kann. Unter Umständen besteht der Popup aus einer Folge von Dialogen (Wizard-Stil). Der Popup soll kein neues Browser-Fenster sein, sondern per Div über der aktuellen Seite als modaler Dialog “schweben”. Dieser Artikel zeigt eine angenehme Lösung für derartige Popup-Wizard-Dialoge unter Verwendung von Java Server Faces (JSF) und Ajax4JSF (A4J).
Das Singleton-Pattern – meiner Erfahrung nach, ein sehr häufig verwendetes Pattern, welches nahezu jeder Entwickler in seinem Wortschatz hat. Die Implementierung des Singleton-Patterns für eine bestimmte Klasse sieht vor, dass eine statisches Feld in der Klassen die Referenz der einzigen Instanz derselben Klasse speichert. Eine Methode “getInstance” liefert diese Referenz zurück und instanziiert falls nötig die Klasse. Der dazu notwendige Code muss jedes mal von Hand implementiert werden. Mit AspectJ und einer Java Annotation soll das Erstellen von Singletons vereinfacht werden. Im folgenden wird eine Lösung vorgestellt mit der eine beliebige Klasse zum Singleton gemacht wird, indem diese die Annotation “@Singleton” erhält. Fortan liefert das Instanziieren der Klasse (“new”) immer ein und dieselbe Instanz. Continue reading »
Mehrfach verwendet man im Datenmodell / Domänenmodell ein Attribut, welches “dateCreated” oder ähnlich heisst. Für eine Entität soll also hinterlegt sein, wann diese erstellt worden ist. Hat man erst einmal ein solches Attribut an einer Entität, so muss das Erstellungsdatum auch beim erstmaligen Persistieren der Entität gesetzt werden. Wie kann man derartiges unter Verwendung der Java Persistence API effizient umsetzen?