Monday 26 October 2015

License Analysis with Maven

Last week I learned about the License Maven Plugin's real value. As developers, we usually just want to do our work and therefore become upset about "unimportant" things that get in our way. One of these things that we don't like to think about are licensing terms. When we find a library, we want to use it - and not undergo a tedious governance process which includes a deep analysis of the library's license, the library's dependencies' licenses, the dependencies' dependencies' licenses etc.
For me, it's "always" been normal just to grab the dependencies that I need from "somewhat" trustworthy sources. However, when you develop commercial software, there are some legal implications. One of the main considerations is the license question. And since more and more libraries depend on other libraries themselves, you must examine the whole tree. Doing this manually can take up a lot of time.
Take for example the Smooks library I'm currently looking at. It's more than a library; Smooks defines itself rather as a framework. It is used to process different data file formats and perform transformations between them. The project has been in development for several years now and as such "naturally" picked up a lot of 3rd party dependencies over this time.
Now imagine yourself sitting there as a developer who wants to use this library (or in this case framework). So you go ahead and add it to your maven dependencies. You mention this to your colleagues/team lead/... Suddenly, somebody with authority steps in and asks: "Did you check the license terms? And what about all the dependencies we're pulling in transitively now?"
This situation is far more common than most of us will like to admit. Of course, you can now go ahead and check the specific library's license, then look at its dependencies and do the same with these - all manually. But if the dependencies have dependencies which again have dependencies and so on... - well, you get the picture. This will probably work out quite fine for a simple library with dependencies that go no deeper than two levels. Beyond that, you can decide to either keep an intern busy for a day or two - or look for a technical tool.
The technical tool I found is the above mentioned License Maven Plugin. The usage page is a bit massive, but for my relatively simple purposes, these steps were sufficient:
  1. Add the plugin to the build section within the main Maven POM:
    <build>
         <plugins>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>license-maven-plugin</artifactId>
                 <version>1.8</version>
             </plugin>
         </plugins>
    </build>
  2. Call mvn license:aggregate-add-third-party. In case of a single module project, you'd instead use the goal add-third-party.
  3. This will produce a file called THIRD-PARTY.txt in the folder target/generated-sources/license of the project you made the call in.
  4. This file lists all dependencies (including the transitive ones) in all child modules with their associated licenses (or Unknown license if that particular dependency contains no license information).
This file is what you can pass on to whoever asks you this kind of annoying question. Enjoy!

Wednesday 22 July 2015

So THAT's what LinkedHashMap is for!

One often cited phrase in Software Craftsmanship is "Know Your Library". This came in quite handy in my latest contribution to the GreenMail project.

My current dayjob project uses GreenMail for simulating a receiving email server as part of testing the ones sent by our system. Every now and then, we have to restart the server, because the heap space has run out - by default, GreenMail stores all received emails in memory. Not much of an issue by itself, but if it happens too often, we'll just waste too much time.

We have similar simulators for other messaging channels such as SMS or Push Notifications. Like GreenMail, the Push simulators just stored all received messages in an unbounded ArrayList which was constantly growing until it exploded. We fixed this by replacing the ArrayList with Guava's EvictingQueue.

My initial idea for the GreenMail fix was the same, but the project coordinators are keen on keeping 3rd party dependencies as low as possible, so they rejected a Guava-based solution. However, I remembered how my former coworker Rafal had solved the issue for the SMS simulator which needed a Map- instead of a List- (or Queue-)based solution.

One standard Java class that a lot of people have heard of (or maybe even briefly scanned the first paragraph of Javadoc), but don't really know, is LinkedHashMap. Most Java devs will know this class as a HashMap with predictable iteration order - something we hardly ever need, so no need to feel bad if you (like me) never bothered to look at its full Javadoc in depth.

So in case you never did that, you will have most likely missed a very special method which is only part of this class and doesn't exist in the Map interface: protected boolean removeEldestEntry(Map.Entry<K,V> eldest).  Let's take a brief look at its JavaDoc:
Returns true if this map should remove its eldest entry. This method is invoked by put and putAll after inserting a new entry into the map. It provides the implementor with the opportunity to remove the eldest entry each time a new one is added. This is useful if the map represents a cache: it allows the map to reduce memory consumption by deleting stale entries.
Sample use: this override will allow the map to grow up to 100 entries and then delete the eldest entry each time a new entry is added, maintaining a steady state of 100 entries.
private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest) {
   return size() > MAX_ENTRIES;
}
At the end of the day, an InMemoryStore is really no different from a cache. And the above example is pretty much exactly what we require it to do: Always purge the oldest message once a certain number is reached.

So on this base I created a simple utility class inside the GreenMail project which extends LinkedHashMap and provides exactly the required functionality. Starting from this, I was able to extract and abstract the methods needed to provide a somewhat easy way to exchange the existing List-based implementation for one based on the new Map class. Please feel free to explore the other parts of the changes for Issue #62 and ask any questions that may arise.

And always remember to Know Your Library.

Friday 24 April 2015

Meine persönliche JAX

Nach zweimaliger Abstinenz habe ich mich 2015 mal wieder zur JAX begeben. Das Programm war wie stets ansprechend gestaltet, wenngleich mich die Auswahl im Vergleich zu früheren Jahren doch etwas enttäuschte. Nichtsdestotrotz war für den geneigten Professional noch mehr als genug an abwechslungsreichen Sessions zu finden.

Hier nun mein ganz persönlicher, total voreingenommener Bericht:

Tag 1: Dienstag, der 21.04.2015

Da ich erst an diesem Morgen aus Wales anreiste, verpasste ich notgedrungen die Eröffnung sowie den ersten Session-Durchgang. Pünktlich zur Kaffeepause traf ich dann endlich ein. Als erste Session hatte ich mir Thilo Frotschers "Eventbasierte Architekturen mit Java EE" herausgepickt. Kurz gesagt stellte Thilo CDI Events vor, mit denen ich schon gearbeitet hatte. Vermutlich genau deswegen konnte ich aus dieser Präsentation, die an sich ganz gut gestaltet war, nur sehr wenig herausziehen - ich hätte mir mehr Tiefe gewünscht, aber Thilos Idee war halt eine andere.
Nach dem Mittagessen folgte mit Lars Röwekamps "Not your Father's Java EE" und seinen Chuck-Norris-Regeln ein Vortrag, der mir persönlich deutlich mehr zusagte. An sich erzählte Lars gar nichts Neues, aber viele Dinge, die einem im Alltag schnell abhanden kommen. Insbesondere habe ich auch schon zu viele Anemic Domain Models gesehen und bin es schon fast Leid, dagegen noch anzupredigen. Nach diesem Talk bin ich jedoch wieder motiviert, diese Prinzipien stärker zu betonen.
Michael Hunger bot mit "Von Relational zu (Big) Graph" gewohnt gute Kost. Überraschenderweise war der Talk selbst für neo4j-Einsteiger gut verständlich - für mich war eher der zweite Teil interessant, wo er tatsächlich mal aufzeigte, wie man eine Migration praktisch durchführen kann. Ach, könnte ich doch nur unsere Entscheidungsträger überzeugen...
Andy Gumbrechts "RunWith(Arquillian.class)" empfand ich leider als maßlose Enttäuschung. OK, ich war zwar ein paar Minuten zu spät, aber Andy beschränkte sich in meinen Augen zu sehr auf die Praxisdemo, anstatt mehr zu erläutern, was da eigentlich passierte. Meine Erfahrungen mit Arquillian, das ich grundsätzlich für ein sehr interessantes Projekt halte, waren bisher aufgrund der meiner Ansicht nach recht hohen Lernkurve leider nicht so gut, und ich hatte mir hier Abhilfe versprochen. Soweit ich mich entsinnen kann, habe ich hier erstmals einen JAX-Talk deutlich vorzeitig (bereits nach etwa der Hälfte) vorzeitig verlassen - und ich war beileibe nicht der einzige.
Den Abschluss bot eine Keynote mit dem stets gut aufgelegten Brian Goetz, die er "Stewardship: The Sobering Parts" genannt hatte. Im wesentlichen ein historischer Abriss zu den wichtigsten Java-Meilensteinen kombiniert mit einem Ausblick auf mögliche kommende Sprachfeatures in Versionen nach Java 9. Sehr gespannt bin ich auf Value Types, mit deren Hilfe man die doch inzwischen sehr künstliche Trennung zwischen primitiven (z.B. int) und Objekttypen (z.B. Integer) mehr oder weniger aufheben können soll.

Irgendwie hatte mir dieser Tag nicht so zugesagt. Insgesamt hatten die Vorträge wenig Neues gebracht, Andy Gumbrecht war sogar völlig an mir vorbeigelaufen. Vielleicht war ich aber auch nur zu erschöpft von der kurzen Nacht und langen Anreise - ich war schon morgens um 1:30 aufgestanden.

Tag 2: Mittwoch, der 22.04.2015

Dank eines verspäteten Busses - darauf ist man halt angewiesen, wenn man auf eigene Kosten reist - erschien ich bereits sehr abgehetzt zu "Andocken bitte!" mit dem mir bisher unbekannten Michael Johann. Von Docker hatte ich schon einiges gehört, aber hier hatte ich wirklich den perfekten Einstieg gefunden. Ich war praktisch sofort infiziert. Man hört zwar oft den Claim "In einem Jahr machen das alle", aber hier könnte es tatsächlich stimmen. Wir hatten Docker in unserem Projekt schon auf dem Radar, haben es aber immer wieder verschoben. Jetzt muss ich da wirklich mal mehr drauf drücken.
Ich hatte sehr lange überlegt, mir die Q&A-Session mit Brian Goetz und der mindestens ebenso kompetenten Angelika Langer zu geben, entschied mich aber schließlich doch für "Functional Thinking" mit Neal Ford - bei einem ThoughtWorker macht man nie was falsch. ;-) Zudem empfinde ich Lambdas, Streams etc. nach wie vor ein bisschen wie etwas sehr Fremdes - ich beherrsche zwar die Syntax und setze sie auch ein, wo ich kann, aber diese Sprachmittel sind mir beileibe noch nicht so in Fleisch und Blut übergegangen wie Vererbung, Polymorphie und ähnliche Dinge, über die ich gar nicht mehr nachdenke. Während ich hier nach wie vor mehr Praxis benötige, hat Neal mir doch zumindest ein kleines Stück weiter geholfen.
Die obligatorische SAP-Keynote "Die dunkle Seite von IoT" mit Matthias Steiner gefiel mir sehr, vor allem wenn man bedenkt, dass es eben SAP war, die sich bei Keynotes sonst an Langweiligkeit gegenseitig überboten. Wenngleich er natürlich (es ist ja SAP) geänderte Businessmodelle und ähnliches erwähnte, war der Vortrag auch für mich als Techie interessant.
Von Eric Evans, der sich mit seinem DDD-Buch schon lange ein Denkmal gesetzt hat, hatten sich natürlich viele Leute einiges erwartet. Am Montag hatte er wohl auch einen sehr guten Workshop geleitet, aber seine Keynote "At last, some boundaries!" wollte bei mir überhaupt nicht ankommen. Anstatt mal wirklich konkrete Beispiele zu betrachten, schickten sich Services A, B, C, D, E und F Nachrichten in den Formaten a, b, c, d, e und f und konnten sich damit gegenseitig stören. Oder auch nicht. Oder irgendwie sowas. Irgendwo unterwegs hatte er mich definitiv verloren, weswegen ich mich frühzeitig zum Mittagessen begab.
Nach diesem erneut eher durchwachsenen Erlebnis hatte ich für den Rest des Tages genug vom Experimentieren und beschränkte ich mich auf Vorträge von Leuten, bei denen ich wusste, woran ich war - in diesem Fall Arno HaaseStefan Tooth und Stefan Zörner. Arno erzählte zu "Reaktiven Geschäftsanwendungen" eher aus Architekten- als aus Entwicklersicht. Wie gesagt, bei Arno weiß ich, dass er Ahnung hat und gute Vorträge hält, und er enttäuschte auch hier nicht. Ich konnte einiges mitnehmen.
Stefan Tooths Betrachtung der Netflix-Architektur litt unter dem für diesen Talk unterdimensionierten Watford-Saal. Im Gegensatz zu den Erdgeschoss-Räumen gibt es hier keine erhöhte Leinwand, zudem steht noch eine Säule in der Mitte. Ich konnte von relativ weit hinten die Folien nur zu etwa zwei Dritteln sehen, auch die Luft war aufgrund der hohen Teilnehmerzahl nicht die beste. Das ist natürlich alles nicht Stefans Schuld, der Vortrag selbst war gut gestaltet und zeigte mir leider nur einmal mehr auf, warum es in der hochregulierten Finanzwelt, in der ich mich im weiteren Sinne noch immmer bewege, praktisch unmöglich ist, wirklich agil zu arbeiten. Dennoch war ich ob der äußeren Umstände doch recht froh, als Stefan mit seinem Talk durch war. Lange hätte ich wegen der schlechten Luft wohl nicht mehr durchgehalten.
Sein Geschäftspartner Sefan Zörner zeigte hernach seine Vortragserfahrung in seinem Talk zu Tipps und Tricks zu Architekturüberblicken. Das ist halt Stefans Thema, wozu man ihn quasi um 2 Uhr nachts wecken könnte: "Kannst du mal in einer halben Stunde einen Talk fertig machen? Mr. X hat Probleme mit seinem Flieger und uns deswegen abgesagt." Ich garantiere euch, er könnte - und man würde es nicht mal merken! Stets unterhaltsam, wenn auch vielleicht etwas überzogen an der Stelle, als er klatschte, um vermutlich unnötigerweise noch mal Aufmerksamkeit auf den nach seiner Ansicht wichtigsten Teil seiner Präsentation zu lenken. Außerdem kann man aus Stefans Vorträgen praktisch immer irgendetwas mitnehmen, so auch hier.
Die JAX-Awards und folgende Keynote schenkte ich mir und unterhielt mich lieber mit ein paar Ausstellern, dazu vielleicht mehr in einem späteren Beitrag. Zu Arno Haases "Java-Trickkiste" gibt es nicht viel zu sagen. Dieses jmh-Tool muss ich mir mal bei Gelegenheit anschauen; ansonsten zeigte Arno ein paar nette Spielereien, den Claim "mit hohem Unterhaltungsfaktor" erfüllte er auf jeden Fall - besonderen Tiefgang erwartet man von den Spätvorträgen sowieso nicht mehr, schließlich haben um diese Zeit schon praktisch alle Anwesenden einen langen Tag hinter sich und die eine oder andere Apfelsaftschorle intus.

Der Mittwoch hatte mir unterm Strich deutlich mehr gebracht als der Dienstag. Ich hatte sogar zwischen den Sessions die ersten Teile der Docker-Einführung durchgespielt. So sollte die JAX eigentlich immer sein.

Tag 3: Donnerstag, der 23.04.2015

Meine Lernfähigkeit bewies ich, indem ich einen Bus früher nahm und eine Haltestelle eher ausstieg, so dass ich wenig abgehetzt und mit gutem Zeitpolster zu "Docker für Java-Entwickler" mit Jolokia-Erfinder Roland Huß erschien. Definitiv eine gute Wahl und die logische Fortsetzung von Michael Johanns Vortrag vom Mittwoch. Michaels Präsentation hatte sich hauptsächlich um die Frage "Was ist Docker?" gedreht, während Roland nun die Antwort auf "Und was mache ich damit?" brachte. Gut vorbereitet, ordentliche Demo. Spätestens jetzt fühlte ich mich bereit, nötigstenfalls bis aufs Blut um den Einsatz von Docker in unserem Projekt zu kämpfen.
Kirk Pepperdine erzählte zu "The dark Art of Performance Tuning". Ich hatte ihn noch nie gehört oder gesehen. Als Bilanz kann ich sagen, dass er definitiv weiß, wovon er redet. Der Vortrag war ein Stück weit interaktiv, wodurch er die Teilnehmer gut bei Laune hielt. Dennoch erschien mir das ganze insgesamt zu unrund - ich kann nicht den Verdacht verhehlen, dass Kirk sich für die Vorbereitung keine allzu große Zeit genommen hatte.
Es folgte die vielleicht merkwürdigste Keynote, die ich bei allen drei JAXen, denen ich beiwohnen durfte, gesehen habe. Der Titel lautete "Technologie-Trends jenseits von Java". Eberhard WolffKai TödterOliver GierkePeter Roßbach und Uwe Friedrichsen hielten, jeder für sich, eine Mini-Präsentation zu diesem doch recht weit gefassten Titel. Große Koordination zwischen den fünf erfahrenen Speakern hatte offenbar nicht stattgefunden, ein roter Faden fehlte komplett. Sebastian Meyhen bemühte sich redlich bei seinen Überleitungen, aber letztendlich blieben es fünf unabhängige Kurztalks. Ich kann mich des Eindrucks nicht erwehren, dass hier kurzfristig ein Slot gefüllt wurde, den der Veranstalter ursprünglich für etwas ganz anderes vorgesehen hatte.
Nach dem Mittagessen und der JAX-Verlosung, die mir einen Teilnahmecode für eine Vaadin-Zertifizierung beschert hatte, wandte ich mich wieder der Architekturschiene zu, dieses Mal in Gestalt eines Vortrags mit dem reißerischen Titel "Know Your Enemies". Gernot Starke hatte ich noch nie erlebt - wem's ebenso geht, sollte das unbedingt nachholen. Der Mann hat Ahnung und einen hochgradigen Unterhaltungsfaktor. Eine sehr lebendige Präsentation, aus der ich einiges herausgezogen habe - so sollte es eigentlich immer sein...
"Mobile Push for the Enterprise" ist sicherlich eher ein Nischenthema, mit dem ich mich aber im aktuellen Projekt schon seit einigen Monaten auseinandersetze. Da wir uns der Schwächen unserer eigenen Lösung bewusst sind, hatte ich mir diesen Vortrag extra schon in der Vorwoche herausgesucht sowie die dazugehörige AeroGear-Website, die zum JBoss-Ökosystem zählt, besucht. Der UnifiedPush-Server löst genau einige unserer zentralen Probleme. Matthias Wessendorffs westfälisch-schnodderige Art mag nicht jedem zusagen, ich komme damit jedoch gut zurecht. Hoffentlich kriege ich die Freigabe, diesen Server in unserem Projekt einzusetzen. Für wen Push ein Thema ist, sollte sich definitiv mit diesem Projekt befassen.
Vor einem wegen Heimreisen schon deutlich gelichteten Publikum durfte Dominik Schadow noch etwas zu "Java-Web-Security Anti-Patterns" erzählen. Für die meisten (wie für mich) ein eher dröges Thema, um das man aber einfach nicht herumkommt. Insofern gelungen, aber unspektakulär. Ich weiß nicht, wie oft Dominik Vorträge hält, aber er wirkte auf mich etwas gequält. Dennoch ein würdiger Abschluss für die Konferenz.

Was gibt's sonst zu sagen? Das Essen war gut und reichlich, auch stand ich gefühlt nicht so lange in der Schlange wie in früheren Jahren - wer weiß, vielleicht waren es weniger Teilnehmer. Ich hatte ein nettes kleines Hotel in Wiesbaden, musste aber jeden Abend darauf achten, noch den letzten Bus zu erwischen. Die Atmosphäre auf der Konferenz war wie immer nett, und ich habe einige alte Bekannte inklusive ehemaliger Kollegen wiedergetroffen.

Unterm Strich hat sich die Reise, die ich dieses Mal voll selbst finanziert habe (das Ticket hatte ich hier gewonnen), definitiv gelohnt. Es wird echt Zeit, dass ich mal meinen Ar... hochkriege und mir ein Thema suche, zu dem ich selbst etwas erzählen kann.

[tl;dr]

Die JAX gibt's noch immer, aber ich war nicht mehr so begeistert wie früher. Docker muss sein. Java ist dank Java 8 wieder da, und ich muss noch immer jeden Tag dazulernen.

Auf bald!