Content tagged java

Reactive Programming with RxJava

posted on

RxJava is an implementation of “Reactive Extensions” (Rx) in Java. But what is this? Originally Rx are an implementation of Microsoft to address the increasing complexity of software. It is a model to build large scale asynchronous service architectures.

Another company that has to be mentioned is Netflix: they implemented the Rx in Java which resulted in RxJava.

On the programming side Rx looks very similar to how streams (java.util.stream.Stream) work. The main difference in my opinion is that streams are pull and lazy. They produce only as much data as someone is reading from them. RxJava on the other side is more push style. The source of data is pushing events through a pipe of operators similar to what you know from streams (filter(), map(), and so on) to the sink. And as I know from this book, Java streams are the wrong tool to parallelize anything that is not CPU bound–like network requests. There reason for this is, that (parallel) streams are executed on a thread pool that is shared with several other features of Java. This thread pools is limited to have only that many workers as the system has CPU cores. Therefore this pool gets exhausted very soon, when threads in it get blocked by I/O operations. Any thread waiting for an I/O operation effectively results in a processor core not used by your program.

RxJava on the other hand is not limited to a fixed thread pool. Any source (Observable) and sink (Subscriber) of data can be bound declaratively to user defined Schedulers. As well as Rx favours a model in which I/O operations are done asynchronously and non-blocking. Therefore resulting in a need for much fewer threads. In a traditional model of using one thread per network connection, threads become very soon the first thing that limits scalability.

What is really great about this book

The best part of this book for me were the reflections on Relational Database Access in chapter 5. While as a developer you might be tempted to convert everything to the reactive model, this part of the book shows where it doesn't make sense to do so.

By converting the access to your relational database to an asynchronous model you won't gain anything. Whatever you are doing on the client side, let's say for example your PostgreSQL will run all of your concurrent requests in different processes. This results in a noticeable limit on the number of parallel queries you're able to run. You cannot lift this limit by becoming asynchronous on the client side.

Links to the book

ZooKeeper, Distributed Process Coordination

posted on

ZooKeeper is a component that facilitates building distributed applications. It is:

The data managed by ZooKeeper is presented in a file system like manner with directories and files whose names get separated by slashes (/). The difference to a file system is, that you can store information in the directories as well. Or seen differently: directories are files at the same time. Based on this simple abstraction, users of ZooKeeper can implement things like leader election in a cluster of software instances.

The book by Flavio Junqueira and Benjamin Reed

The book is written by two experts of ZooKeeper, that know how it works internally and what are the pitfalls in which the users can trap. Flavio Junqueria is one of the ZooKeeper's contributors. Benjamin Reed helped to start ZooKeeper.

I was reading the book, because I is the basis for other distributed software systems I made myself familiar with the last months, including Akka and Mesos. I always think, that it's a good idea to know at least one layer below the layer I am actually using. I allows me to understand better what I'm doing and how to do it right.

The book starts by giving an overview of the concepts and basics used by ZooKeeper. It introduces an example master-worker application, that is implemented using different languages afterwards:

Other topics discussed in the book are:

I think, that this book is a highly valuable resource for anybody working with ZooKeeper either directly or indirectly by using some other software, that uses it.

Links to the book

Mein Weg zur testgetriebenen Entwicklung

posted on

Testgetriebene Entwicklung (TDD) funktioniert – überall. Sie scheitert nicht am Kunden, den nicht Qualität sondern Tempo interessiert. Sie steht nicht im Widerspruch zum jungen Projekt mit wenig Budget, das schnell Kunden gewinnen muss um zu überleben. Sie hindert nicht daran schnell Features umsetzen zu können. Ja, sie macht mir auch nicht (mehr) langsamer.

Es ist keine neun Monate her, dass ich das nicht glauben konnte. Mehrere Anläufe hatte ich unternommen neben Code auch Tests zu schreiben. Länger als zwei Monate ging das nie gut:

Die entscheidenden Hinweise

Test-Driven Development by Example, Kent Beck

Zwei mal klick hat es in meinem Kopf gemacht als ich das Buch „Test Driven Development by Example“ von Kent Beck gelesen habe:

  1. TDD einzuführen ist keine Entscheidung des Kunden, Chefs oder Teams. Das kann jeder für das was er macht selbst tun. Es ist einfach ein Stück persönlicher Programmierstil. Wie ich entscheide, ob ich mir erst auf ein Blatt Papier skizziere was ich programmiere, kann ich auch entscheiden das erst in einem Test zu skizzieren.
  2. Ich hatte davor versucht mit Unit-Tests mehr zu erreichen als ich sollte. Es reicht wenn ich prüfe, dass meine Klasse (Unit) ihre Funktion erbringt und die erwarteten Ergebnisse liefert. Es war falsch zu prüfen, ob mehrere Klassen sich zusammenfügen lassen und gemeinsam richtig arbeiten. Für diese Dinge gibt es Integrations- und Akzeptanztests. Mein Unit-Test stellt nur sicher, dass ich keinen Sonderfall vergesse und sich bei einem Refactoring meiner Klasse (Unit) nichts im Ergebnis ändert.

Mir war klar geworden, dass nicht die Beispiele mit JUnit zu simpel sind, die in fast allen Java-Büchern zu finden sind. Vielmehr war das was ich als Unit betrachtet habe zu komplex. Der Fehler lag nicht in den Beispielen sondern bei mir. Ich hatte meine Probleme nicht so sehr in kleinere Probleme zerlegt, dass sie einfach zu testen sind.

Die ersten sieben Monate

Ein gutes halbes Jahr entwickle ich nur noch testgetrieben. Den Umstieg habe ich geschafft, ich kann mir nicht vorstellen nochmals in die Zeit davor zurückzufallen. Nach einigen Monaten Umstellung habe ich nicht mehr langsamer entwickelt als ohne Tests. Wie bei jeder neuen Technik musste ich am Anfang lernen sie einzusetzen. Das kostet die ersten Wochen und Monate zusätzlich. Dennoch war der Aufand auch damals nicht so hoch wie ich zuvor dachte.

Warum kostet es mich jetzt keine zusätzliche Zeit mehr? Zuerst Tests zu schreiben ist nun eine Struktur in der ich mir Gedanken mache was ich schreiben möchte. Das musste ich auch zuvor tun indem ich Skizzen gemalt, einen Prototypen gebaut oder auch nur Code geschrieben habe, den ich nochmals ändern musste.

Ohne Zusatzaufwand bekomme ich aber die folgenden Dinge frei Haus geliefert:

Was mir sonst noch geholfen hat

Weniger Schlecht Programmieren, Kathrin Passig und Johannes Jander Becoming a Better Programmer, Pete Goodliffe

Zwei Bücher aus den Weihnachtsferien haben meinen Entschluss nur noch mit Tests zu entwickeln gestärkt. In „Weniger schlecht programmieren“ und „Becomming a Better Programmer“ ist mir klar geworden, dass die Professionalität der Entwicklung meine Aufgabe als Entwickler ist. Ich bin der Profi in diesem Bereich und nicht die Geschäftsführung. Diese hat mich dafür angestellt professionell zu arbeiten. Sie verlässt sich darauf, dass ich weiß was notwendig ist und ich dies tue. Wenn ich ihr den Eindruck gebe, es geht auch ohne, wenn es mal sein muss, dann ist klar, dass sie das bevorzugt. Wenn ich der Überzeugung bin, dass es der falsche Weg ist, dann muss ich das vermitteln und darf nicht auf andere schieben, dass es „bei uns“ eben nicht anders geht. Würde ich gegen mein besseres Wissen arbeiten, so hätte zuerst ich versagt und nicht das Management.

Clean Code, Robert C. Martin

Ebenso hat mich der Klassiker „Clean Code“ auf meinem Weg weiter gebracht. Einerseits weil ich durch die Tests erst einiges daraus richtig umsetzen konnte. Vorallem aber weil ich damit gelernt habe auch meine Tests so zu schreiben, dass sie lesbar sind, jederzeit geändert und erweitert werden können.

Java Webstart und WELD

posted on

Für meinen Arbeitgeber habe ich ein Programm entwickelt, das wir nutzen Zeiten zu erfassen und in unser Projektmanagement einzukoppeln. Um in der Firma einfach auf allen Rechnern immer die neuste Softwareversion zur Verfügung zu haben, habe ich mich dafür entschieden Java Webstart einzusetzen. Diese Technik hatte ich auch bereits für einige andere Java-Anwendungen von meinen Kunden eingesetzt.

Neu dieses mal war nun allerdings, dass ich nicht Spring sondern CDI für die Dependency Injection gewählt habe. CDI implementiert durch WELD ist bei uns auf der Arbeit hierzu meist der Standard der Wahl.

Das Problem als ich die fertige Anwendung deployen wollte

Die Entwicklung lief soweit streight-forward. Allerdings habe ich die Anwendung zum Testen nicht wirklich auf einen Webserver gestellt sondern in meinem lokalen Dateisystem installiert. Alle URLs im Webstart-Deskriptor waren deswegen der Art file:///home/matthias/source/zeiterfassung/… und funktionierten super. Die Ernüchterung kam erst als ich die Anwendung mit der endgültigen URL deployen wollte. Als Web-URL beginnt diese natürlich mit https://… und zu meinem Erschrecken macht das WELD Probleme:


Fehlermeldung/Exception in der Java-Konsole

WELD holt sich anscheinend die URL der Java-Archive vom Classloader um darin suchen zu können und der Classloader liefert für die Archive, obwohl er sie schon heruntergeladen hat die Originaladressen mit http://- oder https://-Präfix. Allerdings geht WELD davon aus, dass die URLs auf lokale Dateien zeigen. Bumm, es fliegt eine Exception und nichts startet.

Dokumentiert ist dieser Fehler seit einem guten Jahr als Bugticket WELD-1040 eine Bugfixrelease gibt es dafür jedoch noch nicht.

Workaround

Was tun, wenn ich die Anwendung zum Laufen bekommen will? Im Bugreport ist ein „proposed Fix” enthalten. Mir gefällt dieser Fix nicht wirklich. Es wird hier im FileSystemURLHandler von WELD einfach geschaut, ob eine URL mit „http:” oder „https:” beginnt und in diesem Fall die URL gegen die URL der gecachten Kopie im lokalen Dateisystem ausgetauscht. Das ganze funktioniert so nur ab Java 6, behebt nicht das eigentliche Problem, dass WELD nur spezielle URLs („file:”) versteht und hat sowieso keinerlei Fehlerbehandlung.

Aber gut, da die Anwendung im Moment nur von uns intern genutzt wird und sowieso Java 7 voraussetzt, habe ich mir die Sourcen von WELD besorgt, den Patch eingespielt nur mir selbst Pakete dafür gebaut.

Bleibt zu hoffen, dass der Fehler bald richtig und in einer offiziellen Release behoben wird. Immerhin ist im Bugticket „Fix Version/s: 2.0.0.CR1” gesetzt, das lässt hoffen.

Anmerkung: Wer im Bild oben genau hinschaut sieht, dass aus der URL http://example.com/ tatsächlich http:/example.com/ gemacht wird. Das ist kein Tippfehler in meinem Deskriptor sondern Teil des Verhaltens der ungepatchten Version.

Unless otherwise credited all material Creative Commons License by Matthias Wimmer