Bin ich jetzt schon illegal?

Zum Geburtstag habe ich eine ganz tolle CD bekommen – “le fil” von camille. Gleich in meinen Laptop geschoben, der sie gleich wieder ausgespuckt hat – ist nämlich gar keine CD, sondern “Copy Controlled”. Angeblich funktioniert’s mit MacOSX, aber nicht auf meiner Hardware. Was nun? Einfach auf alle modernen Errungenschaften (iPod, wohnungs-weites WLAN, last.fm) verzichten, was Musikgenuss angeht? Oder eine analoge Kopie aus dem alten CD-Player ziehen und wieder digitalisieren, und auf die aufwändig produzierten und teuer bezahlten kleinen Bits verzichten?

Alles gar nicht nötig. Der gute alte CD-Player hat einen optischen Digitalausgang, mein Macbook Pro einen optischen Digitaleingang, und mit einem TOSLINK-Kabel und einem Adapter auf die kleine Klinkenbuchse des MB Pro kriegt man tatsächlich auf Anhieb 16 Bits bei 44.1 kHz auf die Platte. Ob ich mir tatsächlich die Mühe mache, alles zu zerschneiden, zu taggen, zu mp3ifizieren? Weiß noch nicht. Auf jeden Fall: es geht.

Die “Copy Control” ist nichts weiter als lästig. Ich sehe nicht, wem das irgendetwas nützt.

story

… After a while, yesterday’s decisions will be history, a story about the past that tries to explain the present. That story will be much shorter than all the things we discuss now. But that story is still more than a protocol: Like every good story, it will still contain emotions, condensed ones that go down well with the audience. It takes more than facts to convince us of reality. …

Spring Properties Reloaded

Some time ago, I promised I would describe how to make spring configuration properties reloadable.

When using a standard spring PropertyPlaceholderConfigurer, properties will be read from a file, and their values can be referenced using a ${…} macro syntax. The expanded property values are usually assigned to bean properties in the xml application context.

Now what I would like to have is this: When the file changes, the properties should be read again, and the updated values should be assigned to the original beans’ properties. The standard Spring answer would be “shut down the application context and launch a new one”, but often we can be much more flexible without disrupting operation (e.g. changing the size of a cache etc.)

I came up with the following design goals:

  • Syntax and usage should be as close as possible to the non-reloading standard spring variant
  • Not all placeholders should be dynamic – some bean properties cannot meaningfully be changed at runtime, and the configuration should make this appearant.
  • The same conversions should take place during initial configuration, and when a property is reloaded
  • No extra demon threads – the XML configuration should control when files are checked for updates
  • Spring best practices: programming to interfaces, testability.
  • Singleton beans are enough – there’s no point in reconfiguring instances of templates.

As an example, let’s take a bean whose “cachesize” property is configured using a placeholder “my.cache.size” taken from a property file “config.properties”. The standard spring way to describe this looks as follows:

<bean id="configproperties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="file:config.properties"/>
</bean>

<bean id="propertyConfigurer"
     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="properties" ref="configproperties"/>
</bean>

<bean id="mybean" class="net.wuenschenswert.spring.example.MyBean">
  <property name="cachesize" value="${my.cache.size}"/>
</bean>

The dynamic variant looks very similar, with only some class names changed, and a slightly different placeholder syntax:

<bean id="configproperties"
      class="net.wuenschenswert.spring.ReloadablePropertiesFactoryBean">
  <property name="location" value="file:config.properties"/>
</bean>

<bean id="propertyConfigurer"
      class="net.wuenschenswert.spring.ReloadingPropertyPlaceholderConfigurer">
  <property name="properties" ref="configproperties"/>
</bean>

<bean id="mybean" class="net.wuenschenswert.spring.example.MyBean">
  <property name="cachesize" value="#{my.cache.size}"/>
</bean>

<!-- regularly reload property files. -->
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
   ...(see complete file for details)...
<bean>

If you’re interested – just dive into the code, or download the jar. Thanks to my colleagues at coremedia for discussion and insights – the hacking is all mine, so I take the blame.

I used Spring 1.2.8 plus commons-logging for development (don’t know about licensing, so I’ll rather not bundle the binaries). Try running the example, change the config file and observe the log output. Whoa.

java -cp spring-reloaded.jar:spring.jar:commons-logging.jar   \\
          net.wuenschenswert.spring.example.Main

Implementation

How does it work? In order to get dynamically reloaded properties, we need the following ingredients:

  • a factory bean that detects file system changes
  • an observer pattern for Properties, so that file system changes can be propagated
  • a property placeholder configurer that remembers where which placeholders were used, and updates singleton beans’ properties
  • a timer that triggers the regular check for changed files

The observer pattern is implemented by the interfaces and classes ReloadableProperties, ReloadablePropertiesListener, PropertiesReloadedEvent, and ReloadablePropertiesBase. None of them are especially exciting, just normal listener handling. The class DelegatingProperties serves to transparently exchange the current properties when properties are updated. We only update the whole property map at once, so that the application can avoid inconsistent intermediate states (more on this later).

Now the ReloadablePropertiesFactoryBean can be written to create a ReloadableProperties instance (instead of a Properties instance, as the PropertiesFactoryBean does). When prompted to do so, the RPFB checks file modification times, and if necessary, updates its ReloadableProperties. This triggers the observer pattern machinery.

In our case, the only listener is the ReloadingPropertyPlaceholderConfigurer. It behaves just like a standard spring PropertyPlaceholderConfigurer, except that it tracks all usages of placeholders. Now when properties are reloaded, all usages of each modified property are found, and the properties of those singleton beans are assigned again.

If it doesn’t work for you, I’d love to read your comments. If it does, even more so!

Schmerztraining mit Meister Asai

Über Ostern war Meister Asai für einen viertägigen Lehrgang in Hamburg. Auf 450 m2 Matte verteilten sich 150 Aikidoka, davon mehr als die Hälfte Dan-Träger. Super Gelegenheit, um sich viele viele Tipps abzuholen von verschiedensten Leuten, die es wissen sollten, zumal Meister Asai einen kleinen Vortrag im Gepäck hat zum Thema “Wir waren alle mal Anfänger” und “Trainieren Sie mit unangenehmen Partnern, geben sie ein gutes Gefühl”. Als ungeschickter Anfänger bin ich wahrscheinlich einer der “unangenehmen Partner”…

Wie immer faszinierend ist das Spektrum körperlicher Dimensionen – meine Trainingspartner in diesen vier Tagen wiegen geschätzt zwischen 45 und 145 kg und sind zwischen 140 und 210 cm lang. Und bewegen können sie sich alle – die DIN-Norm für Sportlerkörper spielt hier keine Rolle. Asai meint: Normaler Erwachsener – ob breit oder schmal, lang oder kurz – Sie haben Kraft genug. Sie müssen nur 100% geben. Nicht blockieren. Kraft nach außen schicken.

Die meisten Techniken, die Asai zeigt, hat man hier oder da schon gesehen. Wie er erklärt, ist das kein Problem – wenn jemand zu ihm sagt, “Die Technik kennen wir schon”, dann sagt er “schön, dann zeigen Sie”, und natürlich sieht’s dann nicht richtig aus. Zu wissen, wie eine Bewegung geht, ist etwas ganz anderes, als sie zu kennen/können. Da hilft nur immer wieder üben.

So üben wir ausführlich den Nikkyo: Das Handgelenk wird angewinkelt und ordentlich verdreht, bis die Sehnen elastisch am Anschlag sind, und dann wird durch den Schmerz und das blockierte Gelenk geführt. Asai sagt, natürlich ist das schmerzhaft, deswegen machen wir die Technik ja so, aber man kann sich dran gewöhnen, und mit den Jahren wird man weicher und kann den Schmerz akzeptieren. Einer meiner Trainingspartner erzählt, sie hätten früher so geübt, dass sie nicht abklopfen durften, auch wenn es noch so sehr weh tat. Entsprechend ist er komplett unbeeindruckt von meinen Versuchen; seine Technik bei mir fühlt sich an wie ein Zahnarztbesuch: Der krasseste Schmerz, den ich mir in den letzten Jahren freiwillig habe antun lassen, dann wird die Hand taub, und nach ein paar Minuten kommt prickelnd wieder etwas Gefühl in die Finger. Vieles im Aikido ist sehr gesund, ich fürchte, diese Übung gehört nicht dazu.

Auch Asai sagt, nicht alles könne man üben. Eine Technik enthält einen Hebel, der gegen das Ellbogengelenkt wirkt. Dehnung hilft hier nicht weiter, deswegen üben wir diese Technik auch sehr selten.

Eine meiner Trainingspartnerinnen meint, einige Lehrer hätten geradezu perverse Lust an Schmerzen. S/M-Tendenzen steigern sicher die Lust am Yonkyo, den wir eine Weile üben. Der Knöchel des Partners drückt dabei auf einen Akkupressur-Punkt am Unterarm, dort wo Arterien, Sehnen, Muskelansätze und Nerven schön ungeschützt an der Oberfläche liegen. Asai meint, der Yonkyo “tut weh, was?”, aber hinterlässt keine bleibenden Schäden – “gibt nur braue Frecken”. Er selbst hätte mal einen riesigen blauen Fleck vom Ellbogen bis zum Handgelenk gehabt, aber auch da härtet man wohl ab. Bis ich so weit bin, muss ich wohl damit leben, dass ich noch Tage später nicht vernünftig zugreifen kann.

Der Lehrgang hinterlässt bei mir eine kuriose Mischung aus Selbstvertrauen und Staunen – Selbstvertrauen, weil die meisten Bewegungen und Techniken nachvollziehbar waren, und es sich einfach gut anfühlt, wenn man sie gemeinsam zum Laufen bringt; und Staunen, dass ich mir das angetan habe, und dabei offenbar nichts kaputtgegangen ist. Man hält doch mehr aus als man denkt.

What Begins also Ends

As fine as it is that people start blogging, I am more interested to know when they stop and why. Will you still be blogging tomorrow?

At a time when the word “blog” was becoming commonplace in the mass media, together with unscientific arguments for the blogosphere’s relevance, Micha (a former colleague) asked: when is a blog gone? For example, he himself hasn’t posted for almost 2 months.

Makes me wonder about the giant heap of information garbage we are dumping on our heads. When does a permalink expire?