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?

Enterprise 2.0

It took me the last two days to realize: My boss really means it. The company I work for is being transformed into a Web 2.0 company. Or maybe, the essentials of our corporate culture – in my view: open communication, feedback and individual reputation – are what today is best described as “2.0”. And now our processes and tools follow suit.

The consequence and range of this transformation is still a bit stunning. At the beginning of this week, up to five volunteers were invited to join the management meeting that would make one of the most significant business decisions for this year, our product portfolio. CoreMedia is a software product vendor, its products are its prime investment and source of income, so the decision boiled down to – where is the company going to go.

I volunteered, and here’s where it starts getting unusual: out of those who “volunteered”, the 5 to join the show were not picked – rather, the volunteers were told to decide as a group who should go. Group dynamics galore. We discussed, and in the end made a poll. It felt like a small democracy.

Here we were then, random employees “observing and giving feedback” – watching our directors discuss the company’s future. At first I had assumed that we would just observe, make notes, and help in “viral marketing” of the decisions made. As it turned out, we were actually asked to give substantial feedback, to point out weaknesses, to help in shaping a sustainable solution. And did we take that opportunity! After watching the directors’ discussion for some time (sometimes deeply impressed, sometimes gnawing our fingernails) the roles were reversed, and then our directors had to watch us discussing their “results, the process and their behaviour”! And they were actually listening. Like a discussion on a blog, or a news forum.

The most unusual part is the way decisions will be communicated. There is no committed and fixed communication strategy, no long-fought-over formulations in the final protocol. In the end, after two days of discussion, the feeling was that everyone actually agreed and trusted each other to disseminate the results each in his own way. The communication strategy is – “everyone, go write your view on the internal corporate blog”.

Oh my god, we’re so 2.0. They dare. They are taking it all literally, and chances are, it’s going to work.

Gesundheit!

  • “heisse Zitrone”: frisch gepresste Zitrone mit Honig und heissem Wasser
  • Fliederbeersaft mit Honig und heissem Wasser
  • Rooibos-Tee (oder andere nicht-schwarze)
  • frisch gepresster Orangensaft
  • Clementinen
  • Halsbonbons (nicht zuckerfrei)
  • Inhalieren mit Kamille
  • Inhalieren mit Salzwasser
  • Meerwassernasenspray
  • Nasenspülung mit Emser Salz
  • Gähnen, bewusst Gesichtsmuskulatur entspannen
  • “weit und offen” denken
  • nicht zu viel durch den Mund atmen
  • Kopf hoch lagern, warm einpacken und viel schlafen
  • 36×10 Tempo Familienpackung
  • Dexpanthenol
  • Xylometazolinhydrochlorid (nur notfalls, es droht reaktive Hyperämie!)

…ich hab die Nase voll davon.

Time To Market (for your Domain Specific Language)

“The biggest advantage I can see is […] that the Java language can be extended along certain lines without waiting for the fairly long release cycle to approve and produce something new. It should also take some pressure off the compiler writers, in that some features which previously would require a language change can, in some fashion, be accomplished with closures.”

Patrick Wright on artima

…so keyword arguments and map constructor syntax will be next?

Anonymity

Talking about anonymous abstract concepts in the “ProgLang” category, I noticed that the “axel” concept remains curiously anonymous. No reason, really, just oversight. So here’s how my MacBook sees me.

Note that some people go much further with iSight / Photo Booth…

P.S.: If your iSight stops working and goes all green, as mine did after coming back from repairs (sic), try this and then this – did it for me.

Higher-Order Functions and the Object-Oriented Paradigm

Wow, if I had known my previous post would be read with such scrutiny, I might have left it to ripe a bit longer. I’m really happy to have helped ignite such a balanced and informed discussion!

Originally I intended to post the following as a comment on Reginald’s blog, but I was unable to keep my prose down to a reasonable size… blogs are not the perfect medium for a discussion, but here we go.

The point I tried to make about type checking is that the type checker has no meaningful way to report typing problems if you don’t give him the names, but just a knot of function types. Similarly, if everything is just a list (as in ideal Lisp), the runtime errors can speak of nothing but cons cells.

Reginald, I’m glad you think that the importance of naming things is “obvious” – some programmers appear to think otherwise. Someone might find the task of making up good names unnecessary, or challenging, so they skip it where possible (especially when working in a haste, especially those with a maths/physics background who have learned to deal with pure structure). I consider this bad practice for software, and therefore would not want a programming language to actively encourage conceptual anonymity.

I probably mistook the point of your original post because you set out to answer the question “why should I care about closures, as Java programmer”, but described closures from a purely functional perspective. I believe Java programmers need to care about closures not because the functional paradigm is great, but because of how closures enrich OO programming.

Haskell and ML are much better at domain modelling than Scheme, because of their type system (which is notably absent in Ruby) We can assume “functional-style” programming in Ruby resembles Scheme more than ML, so that’s what I was relating to, given that your examples were using Ruby.

Closures in Smalltalk were originally not full static closures – they were used mostly for control structures and iteration. The full power of closures (as in Scheme etc.) was only added in a later iteration. Which seems to indicate to me that their full power was not required for the “prime use cases” of OO programming – you could still refactor to class-based objects when you needed more.

The Undo/Redo stack is a perfect example of something that should NOT be done using closures. Because each command is not one, but two closures (one for Redo, one for Undo), so which is your object identity?; a command may have a name you want to present to the user (“Undo move” vs. “Undo delete”); and when your software is supposed to persist a command log, or merge commands executed by different users on the same document, you will need a much deeper analysis (instead of just execution) of the commands. Of course you can try to refactor at some point, but searching for all usages and implementations of “Closure.apply” will not produce very meaningful results.

Transactions are another example of more than just a closure – they’ll have an isolation level, a name, an identifier,… Obtaining these property values certainly requires a broader interface than closure.apply(), or another object to wrap the closure, again splitting up object identity. What transactions do have is a Single Abstract Method – did I mention I like the CICE proposal?

So I actually would like a language that is “opinionated” in the sense that it gives guidance. Would you really want to program in an opinion-less language, if such a thing can be imagined at all? How would two pieces of code in that language every fit together? In the Tycoon libraries, each data structure was implemented three times, once functional, once imperative and once OO. Seems wasteful, doesn’t it? All language designs I like express the opinion that “goto” should be rarely used. Don’t you think? In a similar vein, I would like a language to express that most things ought to be named and related to domain concepts.