ng-week: </> + ()-[]->() = b+

Unsere diesjährige Projektwoche stand ganz im Zeichen von JavaScript und Cypher. Wir wollten gemeinsam eine Anwendung entwickeln, die im Frontend auf AngularJS setzt und zur Datenhaltung eine Neo4J-Graphdatenbank verwendet. Die Anwendung sollte dabei ohne (Java-)Backend auskommen. Um das Ergebnis kurz vorwegzunehmen: Das hat super funktioniert!

Als Anwendungsfall diente eine klassische Adressverwaltung: Personen stehen mit Organisationen in Beziehung, Personen besitzen Kontaktdaten, Organisationen haben kontextabhängige Adressen, Personen finden sich in Empfängerlisten für Marketing-Aktionen wieder und vieles mehr. Die Modellierung dieser Beziehungen als Graph ist sehr intuitiv und hat uns gute Dienste als Diskussionsgrundlage geleistet.

Die technische Umsetzung blieb nicht ohne Herausforderungen. Es zeigte sich sehr schnell, dass das Rest-API der Neo4j-DB nicht auf die $resource Abstraktion von AngularJS passt. Auch mit dem $http-Service haben wir uns schwer getan. Wir hätten beinahe einen HATEOAS-Transformer implementiert, wäre nicht Peter – der erst später zu uns stieß – mit der Frage ins Haus gefallen, warum wir nicht den JavaScript-Treiber der Neo4j-DB verwenden. Eine kurze Evaluierung des APIs ergab: Das müsste gehen! Obwohl eine frühe 1.0, erwies sich der Treiber überaus stabil und weitgehend erwartungskonform.

Der JavaScript-Teil hat bei mir gemischte Gefühle hinterlassen. Das Bootstrapping der Anwendung mittels AngularJS war in wenigen Minuten erledigt. Allerdings ein Build-System aufzubauen, wo alle Ressourcen am Ende automatisch an der richtigen Stelle landen, hat mich viel fluchen lassen. Plugins für Grunt scheinen durchweg nichts von Fehler-Reporting zu halten. Eine Inkompatibilität zwischen grunt-usemin und grunt-angular-file-loader war so nur durch Raten zu finden.

Eine weitere Spitzfindigkeit zeigte sich in der Integration des Neo4j-Treibers mit AngularJS. Beide Frameworks setzen auf Promises – allerdings in verschiedenen Implementierungen. Der Neo4j-Treiber nutzt eine eigene, an ES6 angelehnte Implementierung, während AngularJS mit $q einen Service hat, der an den Digest-Zyklus des Frameworks gekoppelt ist. Die Folge war, dass Ergebnisse aus Datenbank-Abfragen nie unmittelbar angezeigt wurden. Peter – diesmal der, der von Anfang an dabei war – konnte den gordischen Knoten zerschlagen. Die von ihm etablierte Verwendungsweise von $q kannte ich bis dato nicht.

Als Fazit lässt sich festhalten: Keiner hat das Java-Backend vermisst. Wir haben uns durch JavaScript, AngularJS, NPM, Grunt, Bootstrap, Less, Neo4j und Cypher gekämpft und selbst alte Hasen konnten dabei noch neue Tricks dazulernen. Wir haben einen funktionsfähigen Prototyp implementiert, deren Fertigstellung im Wesentlichen jetzt nur noch Fleißarbeit ist. Auf unsere Zusammenarbeit und das erzielte Ergebnis können wir durchaus stolz sein.

EJB-TX-Annotationen an privaten Methoden

Mit erstaunlicher Hartnäckigkeit hält sich ein Phänomen in JavaEE Anwendungen: @TransactionAttribute an privaten Methoden. So nutzlos wie irreführend, dokumentiert es die Unkenntnis des Entwicklers über die Mechanismen eines EJB-Containers:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void doSomething() {
  // start a new transaction
  ...
}

Diese Code ist überaus suggestiv und wird gerne in Code-Reviews übersehen. Eine neue Container-Transaktion wird dennoch nicht gestartet. Hierfür müsste der Container einen Interzeptor um den Aufruf von “doSomething()” wickeln. Das wäre einerseits eine große technische Herausforderung und ist andererseits in keiner Weise durch die EJB-Spezifikation gedeckt. weiterlesen

FindBugs: May expose internal representation by returning reference to mutable object

Wer seine Code-Qualität mit FindBugs überwacht, stößt früher oder später auf folgende Verletzung: “Method-X may expose internal representation by storing/returning an externally mutable object into Field-Y”. In den meisten Fällen handelt es sich dabei um das Abfragen und Speichern von java.util.Date Werten.

Erfahrene Java-Entwickler wissen, dass Date-Objekte nachträglich veränderbar (mutable) sind:

Date now = new Date();
now.setTime(1414141414141L);
System.out.println(now);

Dies könnte für Manipulationen ausgenutzt werden:
weiterlesen

Wenn der Wunsch Vater der Dokumentation ist

Der Beitrag könnte Spuren von Emotionen beinhalten. Gerne wird Open-Source-Software mangelnde Dokumentation nachgesagt. Diese Kritik mag manchmal gerechtfertigt sein, auf lange Sicht sind schlecht dokumentierte Frameworks aber einer gewissen negativen Selektion unterworfen – um es vornehm auszudrücken.

Hibernate – das Mapping-Framework von JBoss/Red Hat – besitzt traditionell eine sehr umfangreiche Dokumentation. Diese ist sicherlich ein wesentlicher Grund für die Beliebtheit des Frameworks. Ein Reibungspunkt kann trotzdem entstehen, wenn die Dokumentation Features andeudet, die nicht vorhanden oder fehlerhaft implementiert sind (z.B. HHH-5732). Was mich in den Wahnsinn treibt, ist @NaturalId.
weiterlesen

ICS-Export-Plugin für Redmine auf GitHub

Vor mehr als zwei Jahren begann ich ein Plugin für Redmine zu schreiben, mit dessen Hilfe Tickets als ICS/ICalendar exportiert werden können (Redmine Ticket #1077). Das Projekt – namens “redmics” – wurde ursprünglich auf Google-Code gehostet und fand dort guten Zuspruch. Der Zuspruch war so groß, dass im Laufe der Zeit zahlreiche Mirrors und Forks auf GitHub entstanden. Seit dieser Woche wird das Projekt selbst auch auf GitHub verwaltet (https://github.com/buschmais/redmics). Happy Forking!

 1 2 3 4 5 6 Vor