Things I have learned in the last few months

A few weeks  ago I had a talk with one of my co-workers in which he said he had not evolved technically and personally in the past months. Aside from the fact that I had a different view it made me think of my own current situation. Which insights did I achieve in last few months? Take this post as a personal retrospective of the last few months.

Seeing myself

Not doing sports makes me feel uncomfortable

I had to take a break for a few days which made me feel real uncomfortable. On the one hand I felt really anxious, on the other hand I had the feeling that I had not accomplished anything. Doing sports almost every day and then having to take a break is a situation I can hardly deal with. It has been written by SpOn that doing sports regularly it pushes you into a addiction. Having smkoed cigarettes for years I can confirm that sports has replaced cigarettes as my addicted-to-drug.


Having money is nice, but…

I have always been the person who uses his clothes and tools until they fall apart. This attitude started in my teenager years. Listening a lot to punk rock music and going to concerts could be one for reason for my behavior, I am not really sure about this. During this time I had a real good friend who supported me mentally and financial by donating me without ever wanting a reward. She always said making a gift to other people makes her feel better than buying something for herself. 12 years later I remembered her words again and determined that buying myself something new just for having something new without real usage does not make me happy. Instead I want to pass on the attitude of spending some useful things to people who are really happy about donations. I started my project this month by donating some money to Stratum0 and endowing Mike Pfingsten for his visit at the Entwicklerstammtisch Wolfsburg. My plan is to do one or two smaller donations every months for people or projects inside the IT community.

Talk less, act more

Planning projects or designing processes is really funny but sometimes I am in the situation in which a topic is talked to dead. You know it from roasting a steak: At some point the steak is so tough that you can break someones bones with it but not eat it any longer. If hou have reached this point take the initative and act or nothing will change.

To be honest, in my personal life I follow this rule a little bit too often. This results often in “rollbacks” which cost everyones time. This is definitely one of my weak points which I am trying to reduce.

Procastrination is not always bad

I must admit, after finishing my study at the beginning of the last year I got really lazy with my personal projects, e.g. publishing Nostradamus/prophetr. It is a pity not to deliver my own product but I feel much better with playing some games, reading books or doing sports. Eventually your own state of mind is all that matters and currently I am feeling really balanced.

Delegate work

At some point of my work life I realized that I can’t handle everything and had to delegate tasks. In the first few weeks it was very hard. I had the feeling I had lost control. I had to learn that delegating work means having trust in somebody elses capabilities.

Seeing others

Follow your own rules

Making rules for others means you have to follow your own rules, too. Bending your own rules results in a loss of your authenticity and reliability.

Most people won’t change

Until a few years ago I had the confidence that people can change. Sadly, I must admit, this perspective had changed in the last years. I had to accept the fact that most people can’t or don’t want to change even if this would be the better option.

My motiviation is not your motivation

Having a lot of intrinsic motivation is really powerful. Apart from a few exceptions I am achieving most of my goals. Although I can taint other people with my motivation I can not expect them to have the same level of motivation I have.

Define the roles

Every team member should have a defined role. This role should be written down where everybody can look it up. I am the opinion having a defined role makes you stronger. You have a work identity and the responsibility to push your role topic forward.

Technically faults I made

Making a personal retrospective means admitting my own faults, too.

Using .local as a internal TLD domain

Eh… well.. I set up our company domain with the .local TLD two years ago. In retrospect this decision had led to so much problems like not being able to resolve DNS names because the .local TLD infers with Bonjour protocol. Switching the domain name inside a Windows network is not so easy. I regret the decision every day.

Commit the Eclipse settings to your Git project

I did know that this was probably a bad idea but I had the sligthly hope that it would work. Making things short: It did not work. Never ever ever store your IDE settings in the repository if you are working with other people.

Technically achievements I made

Making Xtext as one of my default tools

Xtext is one of the strongest tools in my developer toolbox. It helped me in various projects and saved a lot of time and money

Connecting JIRA with our own time tracking tool

Some of our customers have full access to their designated JIRA project instances. Being transparently means to track the work times in JIRA. For accounting we use another internal application so we had to track our times in two different systems. I hacked down a PHP script in a few hours which simply copies all JIRA entries to our internal tracking system. Small script, huge time saver.

Technically Lessons Learned

Spring Integration is powerful

We are using Spring Integration in one project for collecting XML files from multiple servers. Spring Integration fits exactly into our requirements and saved the customer a lot of money.

Java EE 6 is not so bad…

I am still not sure if I really like CDI or if I am troubling with Stockkolm syndrom. Using Dependency Injection without having a third party library like Spring or Guice is nice. One drawback is the different CDI implementations (Weld vs. OpenWebBeans) doesn’t necessarily produce the same result. Developing

… but JSF is

I worked with HTML, jQuery, knockout.js and other frontend technologies, like GWT, for years and I liked it because they are transparently in their behavior. Switching from those techniques to JSF is hard. Hard is an understatement. Awful seems to be better fit. JSF adds an additional layer of abstraction where the interaction between browser and client is no longer easy to understand. Besides the fact that different JSF implementations like Mojarra and MyFaces produces different output.

WebSphere is not so bad at all

From an administrative view, WebSphere must be the holy grail. But why the hell does it take so long to deploy a simple web application? Why does enabling security makes the whole WebSphere administration view so slow?

MSSQL: Database * already exists. Choose a different database name. Cannot attach the file * as database.

I am currently playing around with ASP.NET and its Entity Framework. At some point I wanted to execute all my migrations against a new local SQL Express database. After I had dropped the database in SQL Management Studio, the Update-Database command of the Entity Framework failed with the error ”Database ‘$path.mdf’ already exists. Choose a different database name. Cannot attach the file ‘$path.mdf’ as database” (German translation: “Die ‘$path.mdf’-Datenbank ist bereits vorhanden. Wählen Sie einen anderen Datenbanknamen aus. Die Datei ‘$path.mdf’ kann nicht als ‘$path’-Datenbank angefügt werden.”).

SQL Server Management Studio did not longer show the database as present. A manually executed DROP DATABASE SQL statement only showed that there was not such a database. After checking some other possible error sources (machine.config, web.config and so on), I ended up with downloading sseutil from and dropped the database by hand:

> sseutil -s \.SQLEXPRESS -l # shows all databases in the local SQL Express instance
1. master
2. tempdb
3. model
4. msdb
5. $failed_database

> sseutil -s \.SQLEXPRESS -d name=$failed_database
Failed to detach '$failed_database'

Although I received the detachment error, the database was no longer registered and I was able to execute the Update-Database statement without any problems

Why JPAs persistence.xml sucks

Have you ever tried to develop an Java 6 EE application on different application servers? In production we are forced to use WebSphere AS. I like the configuration interface but that’s all. WAS is not usable during development because the deployment cycles are way too long. Because of this we use JBoss AS 7.1.1 in our development environment. Our application uses Java 6 EE features in service (EJB, CDI) and presentation (JSF, CDI) layer but still uses a DAO layer which is managed by Spring. The DAOs get injected by SpringBeanAutowiringInterceptor. For consistency I had planned to port the Spring DAO layer to Java 6 EE.

First of all our Spring configuration uses the correct database connection settings (Hibernate transaction manager, JNDI name) by a simple environment switch which can be set in the application server. By default, the production configuration for WebSphere is used. If you populate an environment key jndi-jboss, the JBoss settings are loaded on startup. This approach introduced a new architectural complexity but fits exactly our needs. Using JPAs persistence.xml and reaching the same goal should be doable, right?

Well… no. First of all, the JPA configuration is simply not designed to handle different environments. This would not be a problem if an application server specific file like jboss-persistence.xml or ibm-persistence.xml would be used by JBoss repsectively WebSphere. On application startup the application server would load the designated persistence.xml and everything is fine.
My approach was to write a simple parser for properties inside persistence.xml which can be evaluated against system properties, like

 		<!-- Remove the hibernate.transaction.manager_lookup_class setting -->
 		<property name="?(applicationserver.runtime=jboss)hibernate.transaction.manager_lookup_class" value="" />
 		<!-- Overwrite the setting -->
 		<property name="?(applicationserver.runtime=jboss)jta.UserTransaction" value="java:comp/JBossUserTransaction" />

Writing and testing the parser was an easy task so I tried to integrate it in the startup process. JPA has no InitializePersistenceContext handler or something else which is executed on startup. The only possibilty was to extend the Hibernate persistence provider and define my own provider inside the persistence.xml. The idea seemed good but did not work. Persistence providers must be deployed in the application server. JBoss only threw an Persistence Provider not found exception. While I was searching for an easier solution (which probably does not exist – you must deploy the provider inside the application server, at least in JBoss) I came upon a blog post which said, that it is not possible to reference a data source in persistence.xml through a res-ref-name resource. Huh? I do need this, otherwise I am not able to specify the JNDI entry independently from my application server. My jboss-web.xml contains a reference to the JBoss data source while the original web.xml holds the reference to the WebSphere data source.
I reached the point where I decided not to go with a pure Java EE 6 implementation and keep the Spring backend. The only solution is adjusting our Maven build process and creating different EAR artifacts for JBoss and WebSphere, which does not solve the problem to easily deploy the application through Eclipse into one of the application servers.

Update (2014-01-29): I opened a feature request in JBoss’ JIRA ( and put a message on the mailing list. A solution for this problem is to add a check for a jboss-persistence.xml in favour of the original persistence.xml.

Hibernate uses wrong schema during schema validation

Recently I struggled upon the same problem, this guy described. Our Oracle database instance contains multiple schematics with almost the same structure. Every developer has it’s own schema for unit and integration tests. On application startup the Hibernate schema validator calls the DatabaseMetaData.getTables() for every linked entity. The method returns the first table which could be found in any schema. The returned tables are by default ordered by schema name. Side node: I would expect that the home schema of the current user would be prefered. This leads to situation that sometimes the validation fails: a user has already migrated his own schema (schema name app_user_unittest) but the schema for the build server (schema name app_build_unittest) still has the old schema version.

Overwriting DatabaseMetaData.getTables() method is not possible as it resides in the Oracle JDBC driver. Instead, you can use the environment variable hibernate.default_schema which points to to prefered schema. Depending on your development environment, the variable could be set during application startup by the application itself or by a system property through your application server.

Jahresrückblick 2013

Und wieder ist ein Jahr vorüber – und was für eines!

In den ersten zwei Monaten hatte ich noch ordentlich für meine Bachleorarbeit zu tun. Glücklicherweise hat alles geklappt und so kann ich auf mein Studium erfolgreich zurückblicken. In den darauf folgenden Wochen habe ich erstmal quasi nichts gemacht und mir eine Serie nach der anderen angeschaut. War auch gut, da ich tierisch ausgebrannt gewesen bin. Leider hält diese Computer-Lethargie im privaten Bereich immer noch an. Mal schauen, ob das in 2014 besser wird.
Als Belohnung für das abgeschlossene Studium kaufte ich mir im März endlich mal ein neues Bike und das Nexus 4. Ende März machte ich dann auch gleich eine Tour im Elm. War bei Minusgraden und Schnee allerdings doch recht … spannend.

Ab April waren wir auf der Suche nach neuen Azubis für die Firma. Das erlaubte uns den Einblick in einige interessante Persönlichkeiten. Glücklicherweise haben wir wieder super Auszubildende bekommen. Ich bin gespannt, welche Azubis 2014 bei uns starten werden.

Im Juni begann ich, mein wöchentliches Tagebuch zu führen. Mir geht das immer auf den Keks, dass ich nicht mehr weiß, wann was gewesen ist. In den Sommermonaten machte ich auch richtig viel Sport. Ich war (und bin immer noch) regelmäßig Laufen und Bouldern gewesen. Beim Laufen war das Highlight sicherlich der 15km Lauf während eines Sommerregens. Beim Bouldern habe ich gute Fortschritte gemacht. Schwimmen habe ich nach einer üblen Migräneattacke direkt nach dem Training für ein paar Monate ausfallen lassen. Werde ich aber ab nächstes Jahr wieder machen.
Auch sportlich war die Teilnahme beim Kickerturnier in Braunschweig. Leider belegten wir nur den fünften Platz. Nächstes Jahr muss das besser werden. Da wir kurz vor Weihnachten zu der Tischkickermannschaft vom Vfl Wolfsburg – so etwas gibt es scheinbar wirklich – eingeladen worden sind, sehe ich da gute Trainingsmöglichkeiten.

Neben diversen Fahrradtouren, unter anderem im Fallsteingebirge, bin ich mit meinen Kollegen noch beim Monkey Man am Allersee zum Klettern gewesen. Hat Spaß gemacht. Vor zwei Wochen habe ich angefragt, ob die denn planen, eine Boulderhalle hier in Wolfsburg zu eröffnen. Sie denken darüber schon länger nach ;-)

Zwei Wochen nachdem ich mein Knochenmark hab typisieren lassen, habe ich bei meinem Schwiegervater um die Hand seiner Tochter angehalten. Da mein jetziger Schwager zu dem Zeitpunkt gerade in seinen Hochzeitsvorbereitungen gewesen ist, habe ich den Heiratsantrag auf ein paar Wochen später verschoben. Der Junggesellenabschied und die Hochzeit von meinem Schwager fand dann Mitte/Ende Juli in Hannover statt. Das waren zwei grandiose Wochenenden, bei denen ich *echt* viel Spaß hatte.

Wegen des super Wetters bin ich ich diesem Jahr extrem braun geworden. Gut für mich, dass ich während meiner Mittagspause einfach mal ein, zwei Stunden mit dem Bike zum Allersee knallen und dann mich dort in die Sonne legen kann. Ebenfalls bei super Wetter habe ich dann Anfang August Jenny einen Heiratsantrag gemacht. Die Planungen für den Polterabend im Ruderclub und die standesamtliche Trauung im November liefen ausgezeichnet, so dass alles glatt von der Bühne ging und wir jede Menge Spaß (und Freudentränen in den Augen) hatten.

Nach einem sehr warmen Weihnachten mit fast 15°C wurde Silvester im Büro gefeiert. Entgegen meiner Befürchtung war dies wohl mit eine der drei besten (neben der Hausparty und der Party im Hallenbad) Silvesterfeiern. Die Tatsache, dass wir bis um kurz vor acht morgens mit Tanzen (!) verbracht haben, spricht eindeutig für sich.

Das Jahr war wirklich super. Erst im Rückblick merke ich, wie sehr mich doch das Studium auch körperlich gestresst hat. Meine Magenprobleme sind deutlich weniger geworden und man sagt mir nach, dass ich merkbar entspannter sei ;-)


  • Wir sind für unsere standesamtliche Trauung aus unserem Urlaub im Harz wieder zurückgekommen und direkt nach der Trauung wieder zurück in den Urlaub.
  • Trotz Ende des Studiums bin im September bei meinen Mitstudenten in Dortmund gewesen und habe dort erfolgreich Party gemacht
  • Spontan noch das Nexus 5 gekauft. Womit ich das Nexus 4 nur knapp ein halbes Jahr in Betrieb gehabt habe.
  • Viel Sport gemacht, allerdings in den letzten Wochen durch zu viel Parties doch leicht zugenommen.
  • Lecker Steak-Nights. Ist leider durch zu vieler Termine in den letzten Wochen etwas eingeschlafen
  • Entwicklertreffen hier in Wolfsburg war total nett.

Abgleich mit meinen Vorsätzen des letzten Jahres:

  • Endlich mal bei der JUG Ostfalia auftauchen: Tatsächlich bin ich ein paar Mal mit meinen Kollegen bei einem Großteil der Veranstaltungen gewesen
  • Nostradamus endlich an den Start bringen: nope; es wird langsam peinlich.
  • Mehr Holzarbeiten: nope,
  • Gödel, Escher, Bach zu Ende lesen: *räusper*
  • Mein privates Mediacenter fit machen: Jap. Auf dem Zotac ION läuft nun ein XBMC.
  • Eventuell neuen Fernseher kaufen: Nein. Werde ich wohl auch nicht mehr, da ich so gut wie gar kein Fernsehen mehr schaue
  • Bachelor mit 1.0 schaffen: Hell, yeah!

Insgesamt sieht zwar nach wenig aus, aber dieses Jahr ist viel passiert. Für 2014 steht folgendes auf dem Plan:

  • Zum GOP nach Bad Oeynhausen
  • Rocky als Musical in Hamburg
  • Freie Trauung im Sommer mit Family & Friends
  • MTB-Fahrt auf den Brocken. Das habe ich mir selbst eingebrockt. Haha.
  • Studiumstreffen in Dortmund
  • Eventuell Wochenendparty im Schwarzwald mit einigen Kommilitonen
  • Besuch (W-)JAX

Sharing the Spring application context from a WAR with EJBs

Picture the following scenario: You have an Enterprise Application Archive (EAR) which contains an EJB module and a WAR file. The web application uses a Spring application context and the same application context must be – for some reason – shared with your EJB. Using the beanRefContext.xml which points to the applicationContext.xml means that you will instantiate a new application context and have no access to the Spring environment of the web instance.

I used the following method:

  1. Create a @Singleton annotated EJB inside the EJB package which holds the global Spring application context which is shared between EJBs and WAR:
  2. Create a @ManagedBean with eager loading. This bean is loaded on startup of the web application. A @PostConstruct annotated method initialies the Spring context:
  3. Create a new EJB interceptor which inherits from SpringBeanAutowiringInterceptor. The interceptor references the @Singleton annotated EJB for looking up the bean factory:

Unit tests inside Eclipse succeed, unit tests in Maven fail. WTF?

Our new project makes use of Maven as build management tool. Eclipse (STS edition) is used for the development process. A part of the project consists of a transformation process which converts XML files to Java POJOs. Because of the given XML structure we used JAXB in combination with EclipseLink MOXy for this.

After a few weeks of initial development, mainly architectural decisions I prepared our TeamCity instance. The first TeamCity build failed because some of the unit tests throw unexpected errors. I must admit that until this time I had only executed the unit tests through Eclipse and every test case had passed without any problem. My local command line Maven builds were triggered with -DskipTests=true and succeeded too.

The failed build in TeamCity occured through the following JAXB error:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
org.springframework.integration.Message is an interface, and JAXB can't handle interfaces.
	this problem is related to the following location:
		at org.springframework.integration.Message
		at public org.springframework.integration.Message ...

I repeated the test suite on my local machine (mvn test) and the first time it ran it succeeded. Eclipse passed the unit tests, too. At first I suspected different Java/JDK versions on my local machine and the build server, but the versions were the same. So I started with a fresh mvn clean test on my machine and the build failed, too. WTF? Now running the compiled unit test and the source code in Eclipse although resulted in the error above. Re-compiling the code with Eclipse fixed the errors. Eclipse uses Eclipse Compiler for Java (ECJ) during compilation and not javac of the JDK. Could it be a compiler bug? The byte code of both .class files (Maven compiled vs. Eclipse compiled) were more or less the same so this was not the answer.

During debugging the Maven compiled artifacts I noticed that the MOXy compiler was not hit, instead the default implementation was used. Could it be that the file was not copied to the class path? is read by JAXB for initializing/overwriting the default XML context factory. And indeed, the was missing. ECJ copied the .properties file to the target directory but Maven ignored the file.

What did I learned from that?

  1. Fail early – Set up the build infrastructure on the first day of your project and don’t wait until a first prototype is available.
  2. Fail everywhere – Running the tests only in one environment (Eclipse) does not mean that it succeeds in other environments (pure Maven).
  3. Don’t skip tests – Waiting for a local build to succeed sucks. Skipping the unit tests makes it better, but a failed build in another environment (see 2.) although sucks.

Fixing segmentation fault in libapt-pkg

I received the message “Segmentation fault” while running an apt-get install. My syslog contained the following lines:

Aug 11 11:34:19 srv kernel: [65729.407484] check-new-relea[12700]: segfault at 7f2dfd94746c ip 00007f2dfc0becd8 sp 00007fffd0671d20 error 4 in[7f2dfc069000+11c000]
Aug 11 11:35:52 srv kernel: [65822.603384] apt-get[12820]: segfault at 7f7d256e346c ip 00007f7d24252cd8 sp 00007fffdbb89140 error 4 in[7f7d241fd000+11c000]

I fixed it with

dpkg-reconfigure libapt-pkg4.12

Use your Uberspace server as relay host for your local postfix instance

Here are the instructions for letting your home server send e-mails with help of your Uberspace account. This small guide is based on Ubuntu 13.04. I assume your Uberspace username is $USUSER and your Uberspace host is $USHOST.

Setup an additional mail address


 ssh $USUSER@$
 vadduser local-server
 # enter a non-trivial password
 # the address "local-server" is now available via $

Setup postfix

apt-get install postfix libsasl2-modules bsd-mailx
# choose "Satellite System" for Postfix server type

Change /etc/postfix/

myhostname =
mydestination =, localhost
relayhost = $
smtp_sasl_auth_enable = true
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_password

Add your newly created mail account

touch /etc/postfix/sasl_password
chmod 600 /etc/postfix/sasl_password
vim /etc/postfix/sasl_password
# add the following line
# :wq
service postfix restart

Send a test mail

mail -s "Test" -- -f root@local-server.internal

tail -f /var/log/syslog should now contain something like

Aug 10 19:52:26 srv postfix/qmgr[11620]: 63EDB13C0F83: from=<root@local-server.internal>, size=309, nrcpt=1 (queue active)
Aug 10 19:52:26 srv postfix/smtp[11626]: connect to $[2001:1a50:11:0:xx:yy:zz:x]:587: Network is unreachable
Aug 10 19:52:26 srv postfix/smtp[11626]: 63EDB13C0F83: to=<>, relay=$[95.143.xx.yy]:587, delay=0.64, delays=0.26/0.12/0.19/0.07, dsn=2.0.0, status=sent (250 ok 1376157144 qp 15391)
Aug 10 19:52:26 srv postfix/qmgr[11620]: 63EDB13C0F83: removed

The Network is unreachable is not important, because I don’t have IPv6 enabled.

DevOps: Stop coding and get your stuff documented

You know it: an old project gets reactivated because your customer needs a new feature or has found bug. Meanwhile, the responsible developers have been reassigned to new projects and have no time to finish the task. You are currently not at a 100 percent workload so you get the task assigned. Because of the missing documentation you are busy with the setup of your development environment in the first few hours. After that you spend the next hours (days) with trying to understand the architecture of the application.

This is an experience every developer or system administrator has made for sure: There is no documentation available or the existing documentation is insufficient or outdated. Thereby an appropriate documentation would result in having more time which could be spent for development and testing.

Types of documentation

Besides the inline documentation of the source code and the end user manual other types of documentation exist. Unit and integration tests for example are a good basis for new developers to understand the internal API. Acceptance tests show how the application will be used by the customer and which typical workflows exist.

It does not matter if frameworks like FitNesse or Cucumber are used or everything is tested with “plain” JUnit/TestNG. The essential fact is that the tests document how the application or architecture can be used.

Furthermore, a developer documentation should exist so that new developers can easily incorporate into new projects. A developer documentation describes the basic topics which must be considered during the development process, for example:

  • Where is the source code located? Which branching model is used?
  • With which credentials can I access the development servers?
  • How is th build process organized? How is Continuous Integration/Delivery realized?
  • How to deal with schema migrations?
  • Where are coding styles located?
  • How did I properly set up my development environment?

As the developer documentation has only the developers as target audience and is only used for internal purposes, the architecture documentation could be although read from external persons. For example one of our customer claims a documentation about security-relevant processes and a documentation about the system and application architecture. The documentation about security relevant processes is required during a security certification, the system documentation is a requirement for the deployment in the datacenter.
In the best case the architecture documentation contains all desired information and can be simply forwarded to the customer.

The Ops needs a operational documentation which can be derived from the architecture documentation. The operational documentation contains topics like “Where can the logging be customized?” or “Where can I customize the database connection string?”.

Organisational and project relevant topics with non-technical background are discussed in the project handbook. The project handbook contains topics like repsonsibilities, contact cards, the processes for bugtracking and meeting notes and so on. Target audience for this documentation is the project management.

Include documenting in your company culture

The writing of documentation should be firmly established as central position in your company culture. New employees should seee on their first day at work that the corporate wiki contains all required information. The involvement in discussions and the improvement of existing documents is explicitly requested. This concept can only succeed if every coworker has already realized how important a good documentation is and leads by example.

In my opinion it is the duty of every good developer or administrator to document his work and his decisions. A good documentation makes the difference between a project and a professional project.

Therefore in our company the following dictum exists: “If it is not documented in the wiki or bugtracker it has not been done.”

Use the right tools

One of the biggest faults is the usage of the wrong tools. Making a good documentation means not using Word and Excel in first line. Instead push every information into your corporate wiki so that every project-related person has instantly access to it. I really like Confluence and can only suggest you give it a try.

Templates like arc42 are a really good start for the documentation. Try to make your own templates which are adjusted to your needs.

The right person for the right job

The development and architecture documentation should be written from the responsible architect during the the development of the concept. He knows the big picture and makes the technical decisions. Always document, what leads to your decisions!

The operating documentation can be written by the developers who implemented the application. The architecture documentation can be used as a basis. The internal system administrators should although read the documentation. They know at best which information is expected in such a document.

Writing the end user manual can be a chance for transfering the domain knowledge of the project to new employees who are not directly connected to it. This can only work if every team member is a aware of the fact that the documentation is an important component of a successful project. It is not a job which can be done by anyone. The requirements for writing a good end user documentation are high:

  • Often, the manual ist the first contact between the customer and your application. The manual must be attractive edited und concentrated on the essential tasks of the application.
  • Your customer does not care about any technical explainations in the end user manual. He reads the document because he has to fulfil his tasks. You are probably also not interested in how the wood was cut while you are building up your IKEA shelf.
  • Your documentation is the reference book and will be the first shelter if any questions occur. Describe the functional processes.

A professional end user manual will demonstrate the customer that the application is elaborated and developed by professionals. A good end user manual is making a major contribution in the successful acceptance of your application.

Every document should be read early and regularly by other persons to reveal problems in the comprehension of the documentation.

Lessons Learned

  • Introduce the documentation process as a central building block of your company culture.
  • Use tools like Confluence or arc42 and build your own set of templates.
  • Writing a good documentation is an art like programming is an art.
  • Treat your authors with respect.
  • Writing a documentation is like programming – only on a higher level.
  • Don’t write a developer or architectural documentation after the project is done. Write it at the beginning of the project.
  • Keep your documentation up to date.
  • Documentation is an important component of your application.
  • Documenting is a continuous process which has to be reviewed at the latest after the project has finished.

Footnote: If you liked the blog post, you would probably like Jens’ blog post about software documentation.