Category Archives: software

Gradle wartet auf Service in Docker Container

Im Zusammenhang mit automatisierten Applikationstest war in einem späteren Schritt einer Deployment Pipeline eine Applikation in einer Testumgebung zu starten, um danach JUnit-Tests auszuführen. Die Applikation war eine Spring Boot Applikation innerhalb eines Docker Containers. Als Build Tool kam Gradle zum Einsatz. Wenn man nun mit Docker den Container startet, dann beendet das Docker CLI sofort nachdem es den Java-Prozess innerhalb des Containers gestartet hat. Will man nun sofort mit den Tests beginnen, dann ist die Spring Boot Applikation aber eventuell noch nicht vollständig gestartet und die Tests schlagen fehl. Continue reading

Terraform und Exoscale

Derzeit bin ich mich am Umschauen, welche Cloudprovider in der Schweiz vorhanden sind und welchen Service sie in Bezug auf Automatisierung anbieten. Einer dieser Provider ist exoscale. In diesem Artikel möchte ich kurz beschreiben, wie ich Compute-Instanzen in Exoscale in Kombination mit Terraform erzeugen und wieder löschen kann. Eine solche Aufgabe nicht via einem graphischen User Interface zu machen - das von Exoscale ist sehr gut - sondern in Source Code zu formulieren, macht die Verwaltung der Infrastruktur in einem Source Code Repository möglich - Infrastructure As Code. Continue reading

Test-Säulen und Test-Treppe (Test-Pillars and Test-Stairs)

Wer sich mit Continuous Delivery und Testen auseinandersetzt kommt früher oder später an der Testpyramide vorbei. Die Mehrheit aller Tests sind Unit Test's, darauf aufbauend wird auf Stufe Komponenten oder Services getestet und ganz oben auf der Pyramide wird die Gesamtheit des Systems getestet. Nach oben wird die Anzahl der Tests kleiner. In diesem Artikel möchte ich einen Weg beschreiben, bei dem die Tests der oberen Stufen auch in den Tests der unteren Stufen ausgeführt werden und um weitere Tests auf jeder Stufe ergänzt werden. Das Ergebnis ist eher eine Stufenpyramide und das Vorgehen führt erstaunlich einfach an Domain Driven Design heran. Continue reading

Wie schnell bringt mein Unternehmen eine index.html Seite in die Produktion? (The Zero Dev Walk)

DevOps und Cross Functional Teams sind in aller Munde und wer es noch nicht kennt, dem sei das Buch "The Phoenix Project" von Gene Kim, Kevin Behr und George Spafford sehr empfohlen. Wie aber bekommt man aber nun ganz konkret heraus was zu tun ist? Was sind die konkreten Schritte, die gemacht werden müssen, damit eine DevOps Kultur entsteht? Continue reading

Docker 1.9.1 hängt mit Docker Toolbox auf Windows

diese Woche ist das Problem aufgetreten, dass auf den Entwicklerrechnern Docker Container einfach hängen geblieben sind und nicht mehr reagiert haben. Die Umgebung war ein Windows® 7 Prof mit Docker Toolbox. Der Fehler trat beim Starten einer docker-compose Konfiguration mit 4 Containern (zwei JBoss, zwei PostgreSQL) auf. Auch ein docker-compose stop oder rm -f war bei dem hängenden Container nicht mehr möglich. Windows zeigte an, dass ein Prozessor bei 100% ausgelastet ist. Bei einigen Entwicklern hat es funktioniert, bei anderen nicht. Wie sich herausstellte, war bei Ersteren die Version 1.9.0 der Toolbox installiert, bei denen Zweiten eine Version 1.9.1. Nach der Analyse des Problems, habe ich dann den Issue #18180 gefunden. Dort sind diverse Vorschläge dokumentiert, wie man das Problem lösen kann. In unserem Fall hat es geholfen den storage driver von docker engine auf overlay zu ändern. Wir haben dazu das Script (start.sh) hinter Docker Quickstart angepasst und bei der Erzeugung des Virtualbox Images mit dem Namen "default" noch folgenden Parameter angegeben:
... --engine-storage-driver overlay ...
Dies kann man aber auch direkt auf der Konsole machen, indem man die alte Maschine erst löscht und dann neu mit dem Treiber overlay anlegt:
docker-machine rm default
docker-machine create -d virtualbox --engine-storage-driver overlay default

Veränderungen

in letzter Zeit gab es bei mir einige Veränderungen. Angefangen hat es damit, dass ich überlegt habe, was ich wohl in nächster Zeit gern machen würde. Über die Jahre habe ich von Programmierung, über Projektmanagement und Teamleitung bis hin zur Infrastruktur in vielen Bereich gearbeitet, mich weitergebildet und Erfahrungen gesammelt. Mich interessiert die Softwareentwicklung und ich bin froh, diesem Interesse auch beruflich nachgehen zu können. Insbesondere faszinieren mich die kleinen Dinge. Bausteine die je nach Problemstellung flexibel zusammengesetzt werden können Dazu gehören natürlich die Grundlagen der Softwareentwicklung (Test Driven Development, Software Craftsmanship) auch moderne methodische Ansätze (agile, lean, Domain Driven Design, Continuous Delivery), kleine Tools (vert.x, Ratpack, Spring BootGradle – ich benutze meist Java/JVM) und offene Herangehensweisen. Im Kern geht es mir darum, die Geschwindigkeit bei der Umsetzung zu erhöhen, ohne das wirklich Stress entsteht. Deshalb halte ich den Zeitpunkt für wichtig, wann etwas gemacht wird. Auch schnelle Iterationen über Ideen und nicht erst über die Umsetzung halte ich für zielführend.  Damit verbunden ist eine enge Zusammenarbeit von Fachbereich,  Entwicklungsabteilung und möglichst auch des Benutzers. Die schnelle Verifikation dieser Ideen ist wichtig – möglichst im Tagesrhythmus,  wenn nicht gar schneller –  um den wirklichen Nutzen eines Produktes zu finden. Interdisziplinäre Teams (Business/Development/Operating/QA  – vielleicht BusDevOps 🙂 ) sind dafür äusserst hilfreich. Seit einigen Jahren halte ich nun Vorträge (Docker, Microservices, Component Management) und gebe Workshops (Coderetreat, Continuous Delivery). Ich engagiere mich in der Entwicklergemeinschaft und bin Präsident der Java User Group Switzerland geworden. Meine Frau und ich haben zusammen die Weiterbildungstagung “Open Source an Schulen 2015” organisiert. Zusammen mit Geza (aka @infinitary)  bereite ich den  SoCraTes Day Switzerland vor. Der grösste Schritt war aber sicherlich, mich selbstständig zu machen: 2015 habe ich die Nautsch Gmbh gegründet. Wir sind interessiert an Kunden, die mit uns in einem partnerschaftlichen Verhältnis an Lösungen erarbeiten möchten und dabei an neuen Sichtweisen interessiert sind. Die Grösse des Unternehmens spielt eine untergeordnete Rolle. Ich persönlich habe Erfahrungen sowohl im Start-Up Umfeld als auch in sehr grossen Unternehmen gesammelt. Wenn Sie also einen Partner für die Umsetzung einer Idee suchen, intern ein Team aufbauen wollen und einen Trainer suchen, oder einfach technische Unterstützung benötigen,  helfe ich gern weiter! Sie erreichen mich am besten per E-Mail:

info@nautsch.com

Software Chirurgie

Auf der Fahrt nach Budapest zur CraftConf 2015  hatten meine Frau und ich eine intensive Diskussion über den Begriff “Software Craftmanship” und wie er wohl für das passt was wir in der Software-Entwicklung machen. Es fehlten ihr die Kopfarbeit und die Voraussetzungen bzw. Ausbildung, welche notwendig sind, um in diesem Bereich erfolgreich zu arbeiten. Die Begriffe Handwerker (im Deutschen noch ganz besonders), Architekt und Ingenieur passten nicht so richtig. Wobei ich zugeben musste, dass der Letztere wohl am besten sei. Da wir in der Softwareentwicklung (noch) keine eigenen Begriffe für unsere Tätigkeiten haben, bedienen wir uns Worten aus gekannten Bereichen. Seit der ersten Konferenz über Software Engineering 1968  leihen wir uns die Definitionen aus dem Bauingenieurwesen aus. Die Wahl dieser Metaphern kann aber nur eine Annäherung sein - zu gross sind die Unterschiede. Die physischen Gesetze wie man sie z.B. beim Brücken- oder Häuserbau vorfindet, gibt es in unserem Bereich nicht. Das Serien-Produktionsproblem die es in anderen Ingenieurs-Disziplinen wie z.B. bei der Serienproduktion im Autobau auftritt - bei uns nicht vorhanden. Kopieren ist einfach. Und dann kam der Vortrag “Beyond Features: Rethinking Agile Planning and Tracking” von Dan North und seine Frage ob wohl der Begriff der Chirurgie (engl. : surgery) besser passen könnte. Seine Überlegungen, dass ein operativer Eingriff mi­ni­mal­in­va­siv ausgeführt werden soll, passt sehr gut auf die derzeitigen Bestrebungen im Bereich von Agile, Software Craftmanship und Lean, eine Lösung einfach zu halten und nur die Dinge zu bauen, die wirklich benötigt werden. Hier ein paar Punkte die mir in diesem Zusammenhang durch den Kopf gehen und welche jedem erfahrenen Softwareentwickler bekannt vorkommen könnten:
  • chirurgische Eingriffe müssen schnell ausgeführt werden
  • ein Chirurg muss neben einer fundierten Ausbildung gute handwerkliche Fähigkeiten vorweisen können
  • es gibt einfache und sehr komplizierte Operationen
  • Komplikationen sind keine Seltenheit und man muss situativ reagieren können
  • es ist schwierig die Dauer einer Operation im Vorfeld abschätzen zu können, insbesondere dann, wenn etwas Neues versucht wird oder der Eingriff kompliziert ist
  • ein Team von unterschiedlichen Experten arbeitet zusammen
  • die Qualität der Arbeit hängt stark von den Fähigkeiten der Ärzte ab
  • die Umgebung hat einen entscheidenden Einfluss - im Fall einer Operation muss der Raum sauber sein, die Instrumente müssen bereit liegen und die Maschinen (hoffentlich nicht veraltet) müssen funktionieren
  • es kommen Fehler vor (Instrumente verbleiben im Körper, das falsche Bein wird amputiert)
  • neue Techniken können eine enorme Bereicherung und ganz neue Möglichkeiten bieten
  • Ärzte müssen sich ein Leben lang weiterbilden (oder möchte jemand von einem Arzt operiert werden, der noch mit dem Wissen aus seinem Studium in den 90igern arbeitet?)
  • kommt ein Arzt zu einem Unfallort muss er improvisieren können
  • es bleiben Narben
  • am liebsten geht man zu den besten Ärzten, aber wenn es schnell gehen muss oder man keine Krankenversicherung hat, nimmt man den Arzt, der verfügbar ist
  • es gibt Scharlatane die Heilung versprechen
  • mit jedem Eingriff lernt man hinzu, bekommt Routine und trotz viel Erfahrung kann man es immer noch besser machen
Meiner Meinung nach kann aber die Analogie zur Chirurgie nur eine Metapher bleiben. Aber ich finde sie hat etwas. Auch ich habe das Bild eines Arztes schon oft verwendet. Insbesondere dann, wenn ich mit unerfahreneren  Softwareentwicklern gearbeitet habe. Bei aller Theorie muss man immer im Auge behalten, dass das Ergebnis im Vordergrund stehen muss. Ein Arzt der an einen Unfallort kommt, findet dort nicht die idealen Bedingungen vor wie im Operationssaal. Trotzdem ist es seine Pflicht einem verletzten Menschen zu helfen. Und genau so ist es auch in der Softwareentwicklung. Es bringt nichts nur über die Schönheit unser Implementierung oder den richtigen Aufbau unserer Applikation zu philosophieren, wenn man für den Kunden keinen Nutzen erzeugen kann oder zu spät mit einer Lösung kommt. Im schlimmsten Fall ist der Patient tot. Im Fokus muss stehen, WAS gemacht werden muss um zu helfen - das WIE sollte man dabei aber nicht aus den Augen verlieren. Wer gern etwas mehr Hintergrund zur Wichtigkeit von Metaphern haben möchte, dem sei das Buch "Leben in Metaphern: Konstruktion und Gebrauch von Sprachbildern" von George Lakoff und Mark Johnson empfohlen. Auf jeden Fall werde ich versuchen richtige Chirurgen zu treffen und darüber zu sprechen. Schlussendlich bin ich in dem Bereich ein Laie. Und wenn sonst jemand Interesse hat: Einfach melden.  

From Agile to Software Craftsmanship

Software Craftsmanship Agile ...
a community of professionals over individuals and interactions over processes and tools
well-crafted software over working software over comprehensive documentation
productive partnerships over customer collaboration over contract negotiation
steadily adding value over responding to change over following a plan
 

/ch/open Workshoptage – 12.09.2013 – WS 15: Coderetreat – honing the craft together

20130616_142005_v1

Art Basel 2013 | Unlimited | Chen Zhen | Continua

Jipiii, es klappt. Am 12.09.2013 ist ein Code Retreat bei den /ch/open Workshoptagen. Wer also Lust hat an seine Programmierfähigkeiten zu feilen... es hat noch freie Plätze. Ablauf wird analog sein wie ich es in meinem letzten Post geschrieben habe. Eventuell überlege ich mir noch eine neue Aufgabenstellung, damit es nicht langweilig wird, wenn zu viele Leute schon mal das Game of Life gemacht haben. Freue mich sehr darauf. Es macht immer wieder Spass und man lernt immer wieder dazu... Update 2013-10-07 Hier noch der Link auf die Präsentation die ich beim Workshop an den ch/open-Workshoptagen verwendet habe. Danke nochmals an alle Teilnehmer! Es hat riessigen Spass gemacht mit Euch zu arbeiten.  

Coderetreat

Coderetreat 2012 @ ZurichJa, lange habe ich nichts mehr hier geschrieben und doch ist so viel passiert. Am 8. Dezember 2012 habe ich am Global Day of Coderetreat in Zürich teilgenommen. Bei diesem Anlass treffen sich Softwareentwickler weltweit verteilt an verschiedenen Orten um ihr Handwerk das Programmieren zu üben. Der Anlass hier in Zürich war sehr gut organisiert und hat in den Büros von Namics stattgefunden. Die Rahmenbedingungen:
  • Problem: Conway's Game of Life
  • Test Driven Development
    • schreibe einen Test der fehlschlägt
    • bringe den Test zum laufen
    • refactor den Code
    • beginne von vorn
  • Generelle Regeln für den Code = Xp Simplicity Rules
  • Pair Programming - es sitzen immer zwei Leute vor einem Rechner und arbeiten zusammen an der Lösung
  • Sessions - man arbeitet mit seinem Partner für 45 Minuten an der Problemstellung, dann 15 Minuten Pause zum Besprechen und zum Erfahrungsaustausch
  • Constrains - in jeder Session bekommt man unterschiedliche Rahmenbedingungen die es einzuhalten gilt, dies waren z.B:
    • no return values - keine Rückgabewerte bei Methoden
    • no condititionals - kein if, kein while
    • baby steps - jede TDD Iteration innerhalb von 3 Minuten, dann 2 Minuten, dann eine Minute.
    • ...
Im Zentrum steht das Üben. Es ist nicht notwendig am Ende etwas Funktionierendes vorweisen zu können. Auf diese Weise soll ermöglicht werden, dem Zeitdruck des normalen Arbeitsalltages zu entfliehen und Neues auszuprobieren.  Der Tag war sehr eindrucksvoll und wertvoll für mich. Unter Anderem musste ich feststellen, dass unter Zeitdruck auch besserer Code entstehen kann. Bisher war ich immer der Meinung, mehr Qualität auch mehr Zeit braucht - aber ja, es geht auch anders. Da ich meine Erfahrungen gern teilen wollte, habe ich im April 2013 bei meinem Arbeitgeber Inventage auch solch einen Anlass organisiert und durchgeführt. Das Feedback war generell positiv. Ich empfehle jeder Entwicklungsabteilung solche oder ähnliche Anlässe durchzuführen. Man lernt die Arbeitsweise der Kollegen besser verstehen, übt seine Gedanken über das Programmieren auszutauschen, lernt die kleinen Tricks der Anderen kennen (und wenn es nur ein Shortcut ist),  lernt besseren Code zu schreiben, und, und, und... Wenn jemand Hilfe benötigt, solch einen Anlass zu organisieren, dann meldet Euch einfach. Wer nicht auf den nächsten Coderetreat warten möchte: Hier in Zürich gibt es codersonly. Diese Gruppe von Leuten trifft sich regelmässig am Donnerstag Abend im Cafe Plüsch, um  gemeinsam an  Code-Katas zu trainieren und sich übers Software entwickeln auszutauschen. May the Craft be with you.

Understanding JavaScript via TDD

I got interested in JavaScript via the book "Seven Languages in Seven Weeks" by Bruce Tate. I read it one year ago. The chapter about the prototyping nature of the language "Io" was an eye opener. The book itself is worth to write about - but not today. As every developer I used JavaScript a little bit. But really understanding whats going on is definitely another thing. The last weeks I wrote a little shopping list as a client for my vert.x experiments. It is a single page app and uses knockout.js, jquery and bootstrap for the UI. I use Java as my general purpose programming language since 1997 and I think I know Java quite well. So, I was a little bit frustrated that I don't understand every construct in JavaScript. After playing with some frameworks and CoffeeScript I decided to build up a comparable Test Driven Environment as I use when I developing in Java. I wanted to use a xUnit like test framework. But there are so many test frameworks that it was difficult to decide which one to use. After looking at several post and at stackoverflow I got the feeling that js-test-driver or QUnit are good candidates. Then I found this really good book: "Test-Driven JavaScript Development" by Christian Johansen. Christian uses js-test-driver in his book. The main goal for js-test-driver is to be the runner for the tests. It has also assertions but I wanted to have more readable tests. I heard about Jasmine and a friend (thanks to Patric) also mentioned it. The integration was done in 10 minutes and the tests are better to read now. I really like this BDD style. After a while I thought about a better way to connect a browser to the driver. I didn't want to start a browser every time and press the connect link because I'm writing "Understand Tests" mostly.  Robert C. Martin describes this kind of tests in his book "Clean Code". These tests are very handy to understand a framework, a library or as in my case also language features. I wanted to start the js-test-driver together with something like a headless browser. PhantomJS is such a thing. js-test-driver-phantomjs starts the driver and the headless browser with one simple command. This setup is also very useful for Continuous Integration! Intellij IDEA has also a nice plugin for js-test-driver. Of course, I can write a test in the console of some browser, but if I close the browser the tests are gone. The tests are inside my project now and I can look at the tests as often as I like. And testing the JavaScript-part of my application works the same way as I know it from the Java-World.            

Asus RT-N66U – 64K NVRAM

This is a very short description how I upgraded my ASUS RT-N66U router. My router had a CFE bootloader version 1.0.1.2. This version only supports 32K NVRAM, which was not enough for my DD-WRT configuration. Disclaimer: Following this steps can brick your router. If you are unsure, don't use this description!

Hard Reset

Hard Reset will clear out the NVRAM. For this router use the WPS button, not the reset button.

Upgrading CFE

I followed the original description:¨CFE bootloader update¨.

Install DD-WRT

I installed the Fractal Build version  20202 mega for RT-N66U with CFE upgrade via ASUS Firmware Restoration tool. This Firmware Restoration tool is part of the ASUS RT-N66U B1 Utility (choose your OS -> Utilities).

Result

References:

  1. dd-wrt.com forum "Asus RT-N66U"
  2. dd-wrt.com wiki "Asus RT-N66U"

It’s already September

Some people are complaining about the absence of information on my blog. So, a few lines: As I wrote in my last post, I went to NYC to improve my English a little bit. Writing is still hard for me, but understanding and speaking is better as before. The first picture is a little restaurant at the 8th Avenue / West 38th Street in NYC where I was quite often at lunch time. They have a nice salad bar and the food was always fresh and delicious. I visited a lot of places, especially museums but I  loved to walk through the Prospect Park and to see the skaters in the Central  Park too. I visited the Guggenheim Museum. It saw Rineke Dijkstras Retrospective there and Ghost in the Machine in the New Museum. I found the High Line by accident. I saw a documentary about this place in Switzerland, but I forgot it entirely. But one day I walked the 14th Street from east to west, looked up and thought "Oliver, you know this old rail bridge." Another nice trip was to go to the Coney Island Beach and Boardwalk. I did it together with Masu - a Rapper from Japan (Hey, do you still have a sentence of the day?). Oh, New York City. It was such a great experience!  Greetings to all there, which I met. Special thanks to Heather and Nick. It was fun to stay at your home! On 10 August, I flew back. One week later our family and friends of us went to the dOCUMENTA(13) in Kassel (Germany). After three weeks without my family it was nice  to be reunited. And the last two weeks? Now I'm a tenant in the gleis70 - Mixwerk here in Zurich. I have a table, a chair, power, internet and my computer. I program, I watch the episodes of CleanCoders and I read a lot.  I still try to help vert.x a little bit. But it is more difficult as expected. My first github pull request was rejected, because of to much structural changes.

running all tests of vert.x on a gentoo box

so after setting up the dev environment (btw. IDEA setup was much smoother) I wants to run all tests via
$./mk test
After getting errors like:
Exception in Ruby verticle: no such file to load -- rubygems
or
Exception in Ruby verticle: no such file to load -- json
I figured out that I have to install ruby and jruby properly on my Gentoo box. In short, run the following commands:
$sudo emerge -va dev-java/jruby dev-ruby/rubygems dev-lang/ruby
$sudo eselect ruby set ruby19
$sudo jruby -S gem install json
and add the following lines to your ~/.bashrc
...
export JRUBY_HOME=/usr/share/jruby
export RUBY_HOME=/usr/lib64/ruby/1.9.1
...
Don't forget
$source ~/.bashrc
I used
$equery files jruby
and
$equery files ruby
to find the right directories. Result:
$~/mk test

...

Information: Starting test: test_echo_binary

:test

BUILD SUCCESSFUL

Total time: 2 mins 19.355 secs

vert.x, the new gradle build and Eclipse 4.2

Developing vert.x with Eclipse 4.2:
  1. Fork the vert.x repo at github (help) and clone it to your local machine (let’s say to /tmp/vert.x )
  2. change directory cd /tmp/vert.x und run ./mk eclipse
  3. Install Gradle 1.0 / Java SDK 7 / Eclipse 4.2 (Eclipse Classic)
  4. Optional Install Grovvy Eclipse Plugin
  5. Start Eclipse and import  every project (I can't find a solution to import all at once.)
    1. Import...
    2. Existing Projects into Workspace
    3. Select root directory
      1. /tmp/vert.x
    4. Finish
    5. Import...
    6. Existing Projects into Workspace
      1. /tmp/vert.x/vertx-boot
    7. Finish
    8. ...
  6. Seclect Project vert.x
    1. Right click
    2. Team -> Share Project
    3. Git
    4. Next, Finish
  7. Project -> Clean -> Clean all Projects
  8. Happy Hacking
I read about gradle support in SpringSource STS but I did not tried it.

vert.x, the new gradle build and Intellij IDEA

I just want to show how easy it is to start developing for vert.x with Intellij IDEA 11.1 and the brand new gradle based build system.
  1. Fork the vert.x repo at github (help) and clone it to your local machine (let's say to /tmp/vert.x )
  2. Install Gradle 1.0 / Java SDK 7 / Intellij Idea 11.1
  3. Open Idea and import the project
    1. File -> New Project
    2. Import project from external model
    3. choose "Gradle"
    4. select
      1. Gradle Project: /tmp/vert.x/build.gradle
      2. Gradle home: /opt/gradle-1.0 (this depends on your gradle installation)
    5. Press next and choose
      1. Language Level: 7.0
      2. SDK: 1.7
    6. Press Finish
  4. Press Build -> Make Project
  5. Happy hacking.

2..27 – noch nicht angekommen

So, nun bin ich in der zweiten Woche meiner Auszeit. Einige Leute fragen schon, wie es läuft und wie es geht und was ich so mache... Meine Antwort derzeit ist, dass ich noch nicht angekommen bin. Es fällt mir zum Beispiel schwer 2 Stunden am Stück an einem Buch zu lesen. Mich überkommt immer noch so eine Unruhe. Aber ich habe schon ein paar Erfahrungen gemacht, die ich ohne diese Pause nicht gemacht hätte. Da ist dieses Projekt vert.x . Ich lese jeden Eintrag in der Google Group, jeden Twitter Pieps von @TimFox und jedes Ticket was aufgemacht wird und bekomme so sehr viel von dem Projekt mit. Auch andere kämpfen mit Git und nicht jeder Schalter  ist sofort klar. Warum ist die vorgeschlagen Verzeichnisstruktur von Maven so nett und warum sollte man nicht grössere Codeänderungen ankündigen und dann lange nicht machen. Alle warten darauf und sie kommen nicht... Und mir geht der Code von dieser einen Klasse nicht aus dem Kopf. Da ist dieser Code in org.vertx.java.deploy.impl.cli.Starter :
    private Starter(String[] sargs) {
	String vertxVersion = String.format("vert.x %s", System.getProperty("vertx.version", "0.0.0-UNKNOWN!"));
    if (sargs.length < 1) {
      displaySyntax();
    } else {
      String command = sargs[0].toLowerCase();
      Args args = new Args(sargs);
      if ("version".equals(command)) {
        log.info(vertxVersion);
      } else {
        if (sargs.length < 2) {
          displaySyntax();
        } else {
          String operand = sargs[1];
          switch (command) {
            case "version":
              log.info(vertxVersion);
              break;
            case "run":
              runVerticle(false, operand, args);
              break;
            case "runmod":
              runVerticle(true, operand, args);
              break;
            case "install":
              installModule(operand, args);
              break;
            case "uninstall":
              uninstallModule(operand);
              break;
            default:
              displaySyntax();
          }
        }
      }
    }
  }
...
 
  private void runVerticle(boolean module, String main, Args args) {
    boolean clustered = args.map.get("-cluster") != null;
    if (clustered) {
      log.info("Starting clustering...");
      int clusterPort = args.getInt("-cluster-port");
      if (clusterPort == -1) {
        clusterPort = 25500;
      }
      String clusterHost = args.map.get("-cluster-host");
      if (clusterHost == null) {
        clusterHost = getDefaultAddress();
        if (clusterHost == null) {
          log.error("Unable to find a default network interface for clustering. Please specify one using -cluster-host");
          return;
        } else {
          log.info("No cluster-host specified so using address " + clusterHost);
        }
      }
      vertx = new DefaultVertx(clusterPort, clusterHost);
    }
    String repo = args.map.get("-repo");
    mgr = new VerticleManager(vertx, repo);
 
    boolean worker = args.map.get("-worker") != null;
 
    String cp = args.map.get("-cp");
    if (cp == null) {
      cp = ".";
    }
 
    // Convert to URL[]
 
    String[] parts;
 
    if (cp.contains(CP_SEPARATOR)) {
      parts = cp.split(CP_SEPARATOR);
    } else {
      parts = new String[] { cp };
    }
    int index = 0;
    final URL[] urls = new URL[parts.length];
    for (String part: parts) {
      try {
        URL url = new File(part).toURI().toURL();
        urls[index++] = url;
      } catch (MalformedURLException e) {
        throw new IllegalArgumentException("Invalid path " + part + " in cp " + cp) ;
      }
    }
 
    String sinstances = args.map.get("-instances");
    int instances;
    if (sinstances != null) {
      try {
        instances = Integer.parseInt(sinstances);
 
        if (instances != -1 && instances < 1) {
          log.error("Invalid number of instances");
          displaySyntax();
          return;
        }
      } catch (NumberFormatException e) {
        displaySyntax();
        return;
      }
    } else {
      instances = 1;
    }
 
    String configFile = args.map.get("-conf");
    JsonObject conf;
 
    if (configFile != null) {
      try {
        String sconf = new Scanner(new File(configFile)).useDelimiter("\\A").next();
        try {
          conf = new JsonObject(sconf);
        } catch (DecodeException e) {
          log.error("Configuration file does not contain a valid JSON object");
          return;
        }
      } catch (FileNotFoundException e) {
        log.error("Config file " + configFile + " does not exist");
        return;
      }
    } else {
      conf = null;
    }
 
    Handler<String> doneHandler = new Handler<String>() {
      public void handle(String id) {
        if (id == null) {
          // Failed to deploy
          mgr.unblock();
        }
      }
    };
    if (module) {
      mgr.deployMod(main, conf, instances, null, doneHandler);
    } else {
      mgr.deploy(worker, main, conf, urls, instances, null, doneHandler);
    }
 
    addShutdownHook();
    mgr.block();
  }
Ich habe in der letzen Woche so viel über diesen Zeilen nachgedacht. Meine erste Reaktion war: "Das muss umgebaut werden." Der Boolean "module" ist nicht gut: lieber zwei Methoden runVertical und runModule - ja und dann muss das Auslesen von den Konfigurationsparametern an anderer Stelle gemacht werden... und überhaupt lässt sich das Ding derzeit mit "
vertx version version version version
aufrufen. Kein Fehler - komisch. Ich werde das umschreiben ... macht das Sinn? Dies sind keine funktionalen Erweiterungen - und bekomme ich es so hin, dass es verständlicher sein wird? Unsicherheit!  

half year off

So, mein Sabbatical startet heute. Während eines halben Jahres werde ich mich Weiterbilden und mit Sachen beschäftigen, für die ich im täglichen Geschäft nicht genug Zeit hatte. Mein Arbeitgeber Inventage war so lieb und hat mir ein halbes Jahr unbezahlten Urlaub gegeben. Eine Pause wollte ich schon so lange mal machen. Bisher war es allerdings immer ein Reden darüber. Letzten Februar haben meine Frau und ich, bei unserer Fahrt in den Winterurlaub, wieder einmal darüber geredet und festgestellt, dass es eigentlich jetzt eine gute Zeit für uns wäre. Also, dann machen wir es. Im Prinzip soll alles wie bisher funktionieren. Die Zeit die ich bisher im Büro war, beschäftige ich mich nun mit anderen Sachen. Meine Aufgaben in der Familie bleiben die gleichen. Was habe ich alles vor:
  • Viel lesen. Bei mir liegen so viele Bücher rum, die ich endlich mal in die Hand nehmen möchte. Habe gestern mit "The Annotated Turing" von Charles Petzold angefangen
  • 3 Wochen New York
    • Englisch lernen/verbessern
    • Stadt erleben und anschauen, ich war noch nie an der Ostküste und bin sehr gespannt
  • Software bauen, insbesondere bei interessanten Open Source Projekten helfen,
    • werde mir auf jeden Fall vert.x anschauen.
  • mich mit Single Page Html Seiten/Applikationen beschäftigen, dazu gehört auch das ich in Coffeescript, Knockout, jQuery usw eintauchen möchte
  • mit Leuten treffen
  • und wenn noch Zeit ist
Zumindest habe ich mir dies alles auf die Liste gesetzt. Was passieren wird, werde ich sehen... und protokollieren, werde ich es hier auf dieser Seite. So, let's have fun. vert.x is compiling...

It’s never to late for git.

If not already done, every software developer must try GIT - the fast, distributed version control system. It's such a nice and useful tool. Once every week I find a new little nice feature. The last month I used the git-client together with a svn-remote repository and I will never use the svn client again. It is so handy to have the full history of the repository on my notebook.  I can commit my changes every time to my local repository and merging/branching is just fun.  I'm so much faster ... Here my path to git Here my favorite git client in action (the command line client 😉 :

git command line

There are plugins for eclise, idea, windows, mac... So give it a try and have fun! And if you want to have the little nice prompt add the following lines to your .bashrc:
...
#-----------------------------------
# git in prompt
#-----------------------------------
        RED="\[\033[0;31m\]"
     YELLOW="\[\033[0;33m\]"
      GREEN="\[\033[0;32m\]"
       BLUE="\[\033[0;34m\]"
  LIGHT_RED="\[\033[1;31m\]"
LIGHT_GREEN="\[\033[1;32m\]"
      WHITE="\[\033[1;37m\]"
 LIGHT_GRAY="\[\033[0;37m\]"
 COLOR_NONE="\[\e[0m\]"
 
function parse_git_branch {
        git rev-parse --git-dir &amp;&gt; /dev/null
        git_status="$(git status 2&gt; /dev/null)"
        branch_pattern="^# On branch ([^${IFS}]*)"
        remote_pattern="# Your branch is (.*) of"
        diverge_pattern="# Your branch and (.*) have diverged"
 
        if [[ ! ${git_status} =~ "working directory clean" ]]; then
                state="${RED}?"
        else
                state="${GREEN}?"
        fi
 
        # add an else if or two here if you want to get more specific
        if [[ ${git_status} =~ ${remote_pattern} ]]; then
                if [[ ${BASH_REMATCH[1]} == "ahead" ]]; then
                        remote="${YELLOW}?"
                else
                        remote="${YELLOW}?"
                fi
        fi
 
        if [[ ${git_status} =~ ${diverge_pattern} ]]; then
                remote="${YELLOW}?"
        fi
 
        if [[ ${git_status} =~ ${branch_pattern} ]]; then
                branch=${BASH_REMATCH[1]}
                echo " (${branch})${remote}${state}"
        fi
}
function prompt_func() {
        previous_return_value=$?;
        prompt="${GREEN}${USER:-$(type whoami &gt;/dev/null &amp;&amp; whoami)}@$(type uname &gt;/dev/null &amp;&amp; uname -n) ${BLUE}[\w${GREEN}$(parse_git_branch)${BLUE}]${COLOR_NONE} "
        if test $previous_return_value -eq 0
        then
                # PS1="${prompt}? "
                PS1="${prompt} \\$ "
        else
                #PS1="${prompt}${RED}?${COLOR_NONE}"
                PS1="${prompt}${RED}\\$ ${COLOR_NONE}"
        fi
}
 
PROMPT_COMMAND=prompt_func
I found this script at github and changed it a little bit. Thx to trapni.

The Clean Coder

Habe gestern Abend "The Clean Coder" von Robert C. Martin (Uncle Bob) fertig gelesen. Ich wäre so froh gewesen, wenn ich dieses Buch als Berufseinsteiger gelesen hätte. Es hätte mich so manche Fettnäpfchen vermeiden lassen. Spannend zu lesen war seine Meinung über den "Flow". Dieser Zustand beim Programmieren, oder Arbeiten allgemein, wo man die Zeit vergisst und einem schier alles gelingt. Uncle Bob findet diesen Zustand eher hinderlich, weil man den Blick für das Grosse verliert. Ich denke es hängt ein wenig vom Arbeitsstil ab. Ich habe immer zu Beginn mein Notizbuch vor mir liegen, wo ich den grossen Kontext aufzeichne. Manchmal komme ich dann schon in Flow während ich beim dem Design bin - also einem relativ hohen Abstraktionsniveau. Trotzdem hat mich das Buch etwas kritischer gegenüber dem Flow werden lassen. Einen völlig anderen Blickwinkel auf den Flow hat z.B.  Joel Spolsky (bekannt von dem Blog "Joel on Software").  Er erzählt in einem Interview, wie wichtig er den Flow findet und das er die Büros sogar so gestaltet, das man sich richtig gut in die Arbeit vertiefen kann. Es gibt aber in dem Buch noch sehr viele andere Perlen und Denkanstösse zu finden. Lesen!