Jeden Tag etwas dazu lernen: Versehentliche Abhängigkeiten erkennen und verhindern (Maven Enforcer Plugin)

Das Enforcer-Plugin von Maven kann sicherstellen, dass bestimmte Abhängigkeiten zu anderen Bibliotheken (jars) nicht in der finalen auszuliefernden Datei landen, zum Beispiel Bibliotheken, die nur für automatisierte Tests benötigt werden.

Beispiel für eine Konfiguration des Plugins:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <executions>
    <execution>
      <id>enforce-banned-dependencies</id>
      <goals>
        <goal>enforce</goal>
      </goals>
      <configuration>
        <rules>
          <bannedDependencies>
            <excludes>
              <exclude>junit:*:*:*:compile</exclude>
              <exclude>org.hamcrest:*:*:*:compile</exclude>
              <exclude>org.mockito:*:*:*:compile</exclude>
              <exclude>*:JUnitParams:*:*:compile</exclude>
              <exclude>*:hamcrest-date:*:*:compile</exclude>
              <exclude>*:*:*:test-jar:compile</exclude>
              <exclude>*:snh-commons-test:*:*:compile</exclude>
            </excludes>
          </bannedDependencies>
        </rules>
        <fail>true</fail>
      </configuration>
    </execution>
  </executions>
</plugin>

Diese Konfiguration stellt sicher, dass die gängigen Test-Bibliotheken nicht im produktiven Code verwendet werden.

 

„Milo“ hat Nachwuchs bekommen

Verkleinertes Modell des LEGO-WeDo Roboters "Milo"

Mini-Milo

Hallo!

Darf ich mich vorstellen: Ich bin „Mini-Milo“ der Sohn von meinem Papa „Milo“ (der berühmt-beliebte Roboter aus dem LEGO WeDo 2.0 Set). Ich erkunde gerade die Welt und hab auch schon eine ganz schöne Blume gefunden…

Ich bestehe schon aus 31 handverlesenen LEGO-Steinen und werde bestimmt noch wachsen. Wenn ich groß bin, möchte ich auch so ein toller Roboter wie mein Papa sein!

Unit-Testing: Exceptions testen [Java 8 Update]

In meinem Beitrag Unit-Testing: Exceptions testen habe ich gezeigt, wie sich Exceptions mit JUnit testen lassen, ohne dabei die Teststruktur verändern zu müssen (Arrange-Act-Assert; Given-When-Then) oder zusätzliche Bibliotheken verwenden zu müssen:

@Test
public void methodThrowsException() {
   IllegalArgumentException ex = foo(someIllegalArgument);
   assertThat(ex.getMessage(), is("foobarfoo"));
}

private Exception foo(FooBarFoo fooBarFoo) {
   try {
      subjectUnderTest.foo(someIllegalArgument);
      return null;
   } catch (IllegalArgumentException ex) {
      return ex;
   }
}

Dank Java 8 und Lambdas lässt sich der Code vereinfachen:

@Test
public void methodThrowsException() {
   Exception ex = tryCall(() -> subjectUnderTest.foo(someIllegalArgument));
   assertThat(ex.getMessage(), is("foobarfoo"));
}

private Exception tryCall(Callable<?> callable) {
   try {
      callable.call();
      return null;
   } catch (Exception ex) {
      return ex;
   }
}

Die Vereinfachung besteht nun darin, dass die Methode tryCall in eine Hilfsklasse ausgelagert werden kann – sie ist jetzt unabhängig vom konkreten Testfall.

Veröffentlicht unter Blog | Verschlagwortet mit

LEGO WeDo 2.0: Praxisbericht

Nach den Sommerferien werde ich an der Grundschule meiner Tochter einen Nachmittagskurs „LEGO Roboter bauen“ anbieten. Als Generalprobe habe ich heute mit den Kindern aus der Klasse meiner Tochter dies in drei Gruppen zu je 8 Schülerinnen und Schüler ausprobiert; Dauer jeweils ca. 90 Minuten.

IMG_20160718_120534298Gebaut und programmiert haben wir das Model zum Thema „Zugkraft und Reibung“ aus dem LEGO Education WeDo 2.0 Set. Jeweils zwei Kinder haben mit einem Set und einem Tablet gearbeit. Es war das erste Mal, das ich mit Kindern zusammengearbeitet habe und es hat allen Beteiligten sehr viel Spaß gemacht – allein, Hochleistungssport ist wahrscheinlich weniger anstregend 😉 Meine detailliert ausgearbeitete Planung und Vorbereitung konnte ich jedoch schon nach 30 Sekunden über den Haufen werfen und musste mich ersteinmal in der Situation pausenlos quaselnder Kinder zurecht finden. Auch das war ein Grund für diese Generalprobe. Wichtige Lehre: Immer einen Plan B bereit haben – zum Glück hatte ich noch ein Ersatzset und einmal das fertig aufgebaute Model. Die Kids sind schon tottraurig, wenn ihr Roboter nicht funktioniert, weil sie das falsche Zahnrad eingesetzt haben.

Große Probleme haben auch die eingesetzten Tablets bereitet, die des öfteren die Bluetooth-Verbindung zum SmartHub verloren. Hier half nur ein deaktivieren von Bluetooth und anschließendes reaktivieren. Überhaupt hatten die Kinder hier große Schwierigkeiten, die Verbindung überhaupt aufzubauen, auch wenn ich den SmartHubs vorher folgende Namen gegeben hatte:

  • Ada Lovelace
  • Charles Babbagge
  • Konrad Zuse
  • Christiane Floyd
  • Isaac Asimov

Die LEGO-Kästen und SmartHubs haben ebenfalls diesen Namen bekommen. Dies hat sich als sehr hilfreich erwiesen.

Die Tablets

Zurück zu den Tablets: Zum Einsatz kam fünf Mal das Acer Iconia Tab 10 (Modell 2016, A3-A40). Dieses Tablet würde ich derzeit aus folgenden Gründen für den Einsatz mit LEGO Education WeDo 2.0 nicht weiterempfehlen:

  • Häufige Abbrüche der Bluetooth-Verbindung
  • Keine Möglichkeit, Nutzerkonten einzurichten (trotz Android 6.0 Marshmallow)
  • Akkulaufzeit zu kurz
  • zu laute Lautsprecher

Letzteres ist deshalb negativ, weil die Kids ganz schnell die Videos in der zugehörigen App von LEGO gefunden haben.

Für das Tablet von Acer hatte ich mich entschieden, da es ein vielversprechendes Preis-/Leistungsverhältnis hatte (200 €; Tablets und LEGO Sets habe ich übrigens selbst gekauft und der Schule gespendet) und ein Markenname mir mehr Zuverlässigkeit versprach, als z. B. ein Tablet von Aldi. Tatsächlich hinterlässt mein Medion P10356 jedoch ein wesentlich stabilieren Eindruck, insbesondere bei der Bluetooth-Anbindung. Folgendes scheint mir hier ein guter Praxistest zu sein: Die LEGO App erlaubt es, bis zu drei SmartHubs mit einem Tablet zu verbinden. Für das Tablet von Medion absolut kein Problem, für das Tablet von Acer – Pustekuchen.

Was ich vorher hätte nachlesen können, aber bei Android 6.0 Marshmallow nicht erwartet hatte, war die fehlende Möglichkeit, auf den Tablets lokale Benutzerkonten einzurichten. Dadurch wollte ich verhindern, dass die Kids die Einstellungen verändern oder andere Apps starten. Tatsächlich haben die Kinder das gar nicht erst versucht. Und wenn doch, dann hätte die von mir auf allen Tablets installierte App „AppLock“ das hoffentlich verhindert.

Vor dem Einsatz hatte ich alle Tablets voll aufgeladen und ausgeschaltet. Ein Tablet hat die 3x 90 Minuten nicht überstanden. Auch hier hat sich der Plan B – ein komplettes LEGO Set und Tablet als Ersatz – als Rettung in der Not erwiesen.

Die LEGO App

Meine Befürchtungen, dass die Kinder bei der Bedienung des Tablets und der WeDo 2.0 App von LEGO (Full Version) Schwierigkeiten bekommen würden – ich hielt die Pfeil-Schaltflächen für zu klein – hat sich im großen und ganzen als unbegründet erwiesen. Tablets lassen sich mit dem Finger wirklich kinderleicht bedienen. Doch im Detail.

Das erste, was negativ ist, ist das Einführungsvideo auf der Startseite. Es nimmt den halben Bildschirm ein und die Kids haben natürlich sofort drauf geklickt – tschüss Aufmerksamkeit, denn alle Videos sprechen die Kinder an und bringt sie zum Lachen.

Das Blättern durch die Baueinleitung gestaltet sich problemlos und in den ca. 30 Minuten, die die Kinder für den Aufbau des Modells benötigt haben, herschte angenehme Ruhe, ja manchmal sogar richtige Stille. Wer baut und Teile raussucht, da haben sich die Kinder prima selbst organisiert; eine Hilfestellung in Baumeister und Materialmanager, wie es die Lehrerhandreichungen von LEGO empfehlen, waren gar nicht notwendig. Jungen-Teams waren deutlich schneller fertig als die Mädchen oder gemischte Teams (hier sind dann die vielen Videos dann aber doch wieder ein guter Lückenfüller; andere bauen aus den verbleibenden LEGO Bausteinen teils erstaunlich tolle Konstrukte (Hund, Tech-Mech)).

Komplizieter war dagegen das Programmieren, vor allem, weil die Kinder was anderes als das vorgegebene Programm programmieren wollten. Die eingblendete Tablettastatur hat dann auch die größten Schwierigkeiten verursacht. Der 3-2-1-Countdown hat sich dabei als echter Zeitfresser und Fruststifter erwiesen.

Die größte Herausforderung war, wie schon oben erwähnt, das Herstellen der Bluetooth-Verbindung. Tipp: Die Verbindung erst aufbauen lassen, wenn das Programm fertig ist (zum Ausprobieren, was einzelne Programmblöcke tun, dafür ist in 90 Minuten keine Zeit).

Experimentieren

Eigentlich sollten die Kinder noch ein wenig experimentieren und herausfinden, wie der Roboter mehr Reifen ziehen kann oder sich auf unterschiedlichen Untegründen verhält (ich hatte eine Holzplatte mit, auf der Teile mit Filz und mit einer dünnen Plexiglasscheibe beklemmt waren), aber das sich der Roboter bewegt, hat schon viel zur Begeisterung beigetragen. Die ständigen Abbrüche der Bluetooth-Verbindungen sind jedoch als Frustfaktor nicht zu unterschätzen – oder ein Roboter, der vom Tisch fällt und dann in seine Einzelteile zerfällt…

Erstaunlicherweise bewegen sich einige Modell schneller als andere. Ob da an leicht anderen Aufbauten lag, konnte ich in der Kürze der Zeit nicht herausfinden.

Abbau

Da ich dreimal hinter einander den Exkurs angeboten hatte, musste die Modelle auch wieder auseinander gebaut werden. Dies Durchzusetzen ist fast ein Ding der Unmöglichkeit („Kann ich den nicht mit nach Hause nehmen?“ oder „Robbi hat mir doch gar nichts getan.“) klappt dann aber doch, wobei ich den Kinder die Tablets aus der Hand nehmen musste.

Leider landen die Bauteile nur selten in den Fächern, in die sie hingehören. Hier ist ausreichend Zeit einzuplanen und die Sets nachzusortieren oder fehlende Teile zu identifizieren (meistens haben sie sich dann in einem anderen Kasten wiedergefunden).

Ein Bauteil scheint jetzt aber dennoch dauerhaft verlustig zu sein. Hier werde ich das Ersatzteileseit von LEGO mal ordern und prüfen, ob LEGO da den richtigen Riecher hat, welche Teile am häufigsten verloren gehen.

Auch hier gilt Plan-B: Ein Set als schnell verfügbares Ersatzteillager ist unabdingbar.

Fazit

Kinder und Veranstalter hatten unglaublich viel Spaß und ich freue mich schon auf den Kurs nach den Sommerferien.

Vielen Dank, liebe Kinder der 2c, dass ihr so toll mitgemacht habt!

P.S.:
Dieser Bericht wird noch durch Bilder und Videos ergänzt.

LEGO WeDo 2.0 – Das Vogelnest (Bird’s Nest)

Seit Januar haben Vater und Tochter ein gemeinsames Hobby: LEGO WeDo 2.0, der kleine Bruder von LEGO Mindstorms. Nachdem wir schon die Forschungssonde Milo, den Zugkraft-Käfer und andere Modelle nachgebaut haben, haben wir uns ein wenig auf Youtube nach weiteren Modellen umgesehen.

Die Macher von RoboCAMP haben in ihrem Video das Vogelnest (Bird’s Nest) auf WeDo 2.0 „upgegradet“. Das Video ist detailliert genug, um das Modell nachzubauen:

Vogelnest

Ich hab‘ das mal zum Anlaß genommen und eine Bauanleitung mit dem LEGO Digital Designer erstellt (dem allerdings der Smarthub und die Motoren und Sensoren von WeDo 2.0 fehlen).

Und so sieht das zugehörige Programm aus, das mit der zugehörigen Android App erstellt wird:

Programm

Das Programm wartet nach dem Start darauf, dass sich etwas dem Bewegungssensor nähert. Dann wird der Motor eingeschaltet und läuft so lange, bis sich das Objekt (der Eltervogel) wieder entfernt. Dies wiederholt sich in einer Endlosschleife.

Your Code as a Crime Scene

Coupling between different batch programms

Coupling between different batch programms

In Your Code as a Crime Scene Adam Tornhill presents forensic techniques to find offending code. This figure shows the coupling between four different batch programs. Batch A, B, and C share common datastructures (Common Files) so it wasn’t surprising that there is a dependency between Common Files and Batch A and B. But why was there no dependecy to Batch C? Sometimes missing things can give deep insights…

But we did not expect the dependencies between Batch A, B, and C. What was the reason for this? The solution was surprising: Copied comments with a JavaDoc @link reference that changed during a refactoring… Upps.

And finally the dependency between Batch C and Batch D was a really big anomaly in our code, because these two batches have functional nothing in common.

Thank you, Adam, for your wonderful tool Code Maat.

The figure above is a coupling analysis on an architectural scale. The diagram is based on D3’s curved links layout. The distance between two nodes represents the coupling. A far distance means lesser coupling. The stroke width is the number of revisions from that coupling analysis (and the color is just to please you).

Veröffentlicht unter Blog

Solarenergiefinsternis

Zu meiner Zeit bei einem großen norddeutschen Energiekonzern habe ich an der Website Energieportal Hamburg mitgewirkt. Dort wird u.a. der in Hamburg aus regenerativen Energien erzeugte Strom angezeigt. Die Auswirkung der Sonnenfinsternis am 20. März sind wunderschön zu sehen – und auch, das der Himmel nach der Sonnenfinsternis sehr viel bedeckter war als davor.

Solarenergieerzeugung am 20. März 2015 in Hamburg

Wind- und Solarenergieerzeugung am 20. März 2015 in Hamburg

Ab 10 Uhr nimmt die erzeugte Leistung deutlich ab und erreicht kurz nach 11 Uhr ihr Minimum, um dann wieder anzusteigen (gelbe Linie). Die Prognose (beige Linie) hat die Sonnenfinsternis ganz offensichtlich nicht berücksichtigt.

Die blaue Linie zeigt die durch Windkraft erzeugte Energie (hellblau die Prognose).

Veröffentlicht unter Blog

Unit-Testing: Exceptions testen

Möchte man das auftreten von Exceptions mit JUnit testen, so gibt es verschiedene Wege und Möglichkeiten. Die bekanntesten sind sicherlich

@Test(expected=IllegalArgumentException.class)
public void methodThrowsException() {
   subjectUnderTest.foo(someIllegalArgument);
}

und

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void methodThrowsException() {  
   thrown.expect(IllegalArgumentException.class);
   subjectUnderTest.foo(someIllegalArgument);
}

Beide Varianten haben den Nachteil, dass die Given-When-Then (oder Arrange-Act-Assert) Reihenfolge aufgebrochen wird, so dass man häufig „von Hand“ geschriebenen Code wie den folgenden findet:

@Test
public void methodThrowsException() {
   try {
      subjectUnderTest.foo(someIllegalArgument);
      fail("IllegalArgumentException expected, but not thrown!");
   } catch (IllegalArgumentException ex) {
      assertThat(ex.getMessage(), is("foobarfoo"));
   }
}

Jetzt sind die Anweisungen zwar wieder in der Given-When-Then Reihenfolge, aber die try-catch-Anweisungen machen den Code unübersichtlich.

Die folgende Lösung ist uns in den Sinn gekommen, nachdem wir uns im aktuellen Projekt über Clean Code ausgetauscht haben:

@Test
public void methodThrowsException() {
   IllegalArgumentException ex = foo(someIllegalArgument);
   assertThat(ex.getMessage(), is("foobarfoo"));
}

private Exception foo(FooBarFoo fooBarFoo) {
   try {
      subjectUnderTest.foo(someIllegalArgument);
      return null;
   } catch (IllegalArgumentException ex) {
      return ex;
   }
}

Der Testcode ist sauber, die Reihenfolge der Testanweisungen stimmt und es sind keine Erweiterungen wie @Rules oder catch-excpetion notwendig.

Veröffentlicht unter Blog | Verschlagwortet mit

Domain-Driven Design: First-Class Repositories

Unter anderem findet man in Vaughn Vernon Implementing Domain-Driven Design die Empfehlung das Repositories das Collection-Interface imitieren sollen:

public interface CargoRepository {
   add(Cargo cargo);
   remove(Cargo cargo);
   ...
}

Der Hintergedanke dabei ist, ein Repository nicht als DAO (Database Access Object) zu verstehen, sondern als fachlichen Behälter für aufzubewahrende Dinge – egal wie diese jetzt tatsächlich persistiert werden (Stichwort: persistence ignorance).

Aber warum nicht noch einen Schritt weiter gehen, und ein Repository als First-Class Collection betrachten:

public interface Cargoes {
   add(Cargo cargo);
   remove(Cargo cargo);
   ...
}

Dieser Gedanke kam mir beim Lesen von Jeff Bays Object Calisthenics. Mehr lässt sich Persistenz wohl nicht ignorieren…