Sunday, October 11, 2009

Combining TemporaryFolder @Rule with Spring 3

I like TDD, I like Springs @ContextConfiguration framework and I like JUnit 4.7's new Temporary folder. Getting the latter two to play nice isn't as easy as I hoped, so here's an attempt at a way to make them work.

Let's say you need to configure an incoming directory on a component using external configuration. For example in Spring Integration: <file:inbound-channel-adapter directory=#{config.directories.store} ... />.

I'm using expression language to load a property from a config object, which I wire in turn as a Spring bean. In my main application this config object can just be a for example, and in my test I can override that bean with an inner class from my test.

public static class Config {
public static final Map directories = new HashMap();
}

If you then use the containing context in a JUnit test it will be loaded up once the context is created, so you need to make sure to put the store value in the map @BeforeClass. Now I'd like to use a TemporaryFolder, to store files in the input directory of the channel adapter, but you can't refresh the property of a singleton bean each test. The @Rule will be applied before each test, resulting in the second test using a different directory from the context. A shame.

A working solution is to just remove the @Rule annotation from the TemporaryFolder and manually invoke create() and delete(). I'd like to know if there is a better solution.

Maven sample project can be found on GitHub.

If you give it a go, let me know if you find a neater option!

Friday, September 4, 2009

Spring Milestones and Snapshots with maven

It took me way longer than I wanted to set up a simple maven project using the Spring M4 and the latest snapshot of Spring Integration. For some reason this is not documented prominently on springframework.org. I commit on Spring Integration, so maybe I should do something about this, on the other hand, blogging is easier... I'll hand you the fix that still worked for me in 2009.

I'm a bit of a maven rookie. I've been using it for years now, but I still feel uncomfortable using it and I have given up on ever having a complete grasp of how it works. The general idea and functionality I understand and sympathize with, but other than that it's too painful to recommend. On the other hand, I just want my build to work and learning Gradle isn't on the top of my list if I need to get started now. Maven itself is tolerable but the plugin and repository landscape isn't.

I'm just going to save you 45 (if not more) minutes of searching and cursing before you find hints on the project pages.

Don't use the search tools for maven central (I like mvnrepository) for Spring dependencies.
Don't use SpringSources enterprise repository for milestones and snapshots. They might be there, but they end up there later than on S3.

There is a milestone and snapshot repository in S3, as described by Ben Hale in a blog. Use the repository snippets from that blog (also included here). Look carefully at the url of the s3browser.

Do use http://s3browse.com/explore/maven.springframework.org/

The repositories are in s3, and while that is very cool, it's also a pain for you because you can't explore them with the url copied from the repository element. Keep a comment on that in your pom if you have colleagues.
<repository>
<id>spring-milestone</id>
<name>Spring Portfolio Milestone Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/milestone</url>
<!-- browse via http://s3browse.com/explore/maven.springframework.org/milestone -->
</repository>

<repository>
<id>spring-snapshot</id>
<name>Spring Portfolio Snapshot Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/snapshot</url>
<!-- browse via http://s3browse.com/explore/maven.springframework.org/snapshot -->
</repository>

If you need artifacts from S2's enterprise repository too you can end up with a whopping 6 repository snippets just for your spring artifacts. Keeping track of which artifact comes from which can be daunting. If you're in the position to do so, using Nexus (or similar) can be used to mitigate that.

There are a lot more details to all this (related to OSGi and maven versioning schemes), but if you're just interested in making it work, you should be grand now.

Hope this helps.

Saturday, January 10, 2009

Push vs. Pull or Why company mailing lists are evil

Everybody that works for a large organization knows the semi Observer anti-pattern. In some form or another at least. It works like this: The Big Boss thinks that you need to know, so he pushes information to you through email. He is too lazy to push this corporate spam to all personnel individually so you get added to a list automatically. At least some of your bosses don't know that there is such a thing as BCC so soon all personnel knows all the lists they are on.

The next step is that people start holding discussions using the email addresses for those lists. I've seen these types of discussions spiral out of control in different firms I've worked for. This causes unreasonable load and distraction for the employees and can even cause the whole email system to collapse under the strain. I can tell you this is not the first time something like this has happened.

What makes this behavior unforgivable, is that there is such a simple solution.

Use RSS or newsgroups to let people subscribe to replacements for these lists and clearly separate directed communications (to a few people) from news and open discussions. By using this simple solution (and working for a company that actually does this right), I've managed to reduce my incoming email by 80%. It is still some work to go through all the mails after a few days of inactivity, but the thing is it is not absolutely impossible anymore. The other immensely satisfying improvement is that most mail I get I actually want to read.

I do have thousands of unread items piling up in my RSS reader and nntp client, but those I know I can safely discard when they get stale. They don't eat up disk space and I can always search them.

There are reasons to keep lists in the company anyway. For example some employees are too lazy or stupid to subscribe to RSS lists and newsgroups, if you are legally required to send out a communique an email push might come in handy. In those cases: use BCC. If something should not be done, make it impossible. Guidelines for Reply-All and the pleas and threats to follow them are just more unneccesary noise.

So bosses all over the world, if you read this: be smart and stop spamming your employees, they hate you for it and they're right.

I saw another complaint about many emails in general. I bet that this guy is subscribed to his own blog using email. He ends his post with:
If you are the person with the idea to save us all, send me an email and tell me all about it. Actually, strike that. Drop by my house and tell me all about it. I don’t want your message to get lost in my inbox
I'm not a venture capitalist, but still the difference is striking: my mailbox is completely read, and I spend less than an hour a day to keep it that way.

Sunday, October 12, 2008

Syncing calendars... nothing is ever easy

I have a problem of managing multiple callendars. My wife has access to my Google calendar, my company has access to my Zimbra calendar. I use a Mac, and I like to use iCal if possible. I use Plaxo, TripIt and Dopplr, which provide ical interfaces/synchronisation, just like Google and Zimbra.

All this shouldn't be too original, so I expect that other people have this problem. Granted it is not an easy problem to solve, because synchronisation isn't easy. Let me first explain how I'm managing things now (and how I screw up). Then go over the options and then over what I really want.

Now I manage my calendars through CalDav. This works really well for a single calendar, but it does nothing for you in terms of synchronisation. If my office manager add's an appointment I see it show up in the right calendar, if I get a trip confirmation and send it to TripIt same story if my wife makes an appointment I can see it show up too. Nice overview, clear separation of calendars. Perfect, as long as I do the managing. That is the problem, my wife manages the calender of our private life, my manager manages the calender for the jobs. They have no idea what the other is doing.

So I screw up like this: if my manager plans for me to be abroad he checks with me and puts it in the calendar, then I have to make sure it shows in my private calendar that I'm abroad, otherwise my wife will plan something conflicting in the home calendar.

The underlying problem is that I am just one person, so everybody planning for me to be somewhere needs visibility on where I am. Main options:
  • Be more disciplined and copy things over
  • Use a single calendar and synchronize
The first option is what I'm doing now. Fine tuning this would mean I create a single calendar that lists my availability and make sure that all planners have read access to that from a single interface that they use for planning. The advantage is that this way the planners do not have to worry about fine grained appointments, just about available time (in a certain location).

The second option would allow me to be very lazy, but it would also result in a privacy issue where my manager can see that I went to a party on thursday evening or something. I don't care that much about privacy. I do care about my manager moving around my dentist appointment from the private calendar, so the solution is not ideal.

An ideal situation would allow me to share availability across calendars, and restrict write access and access to detailed information based on different calendars/sets of appointments.

The annoying thing is that there are no tools that allow this. Requirements are:
  • Have to use Zimbra for work
  • Have to use Gcal for private
  • Want to use iCal as interface
  • Want to integrate CalDav calendars
  • No manual syncing
The only way to get close would be to install different sync utilities for my mac and sync with a local calendar. The proper way to do it is to allow CalDAV calendars to be synced in ical, but there is no support for this in iCal natively. The only workable solution (other than discipline) is to run sync utilities like Spanning Sync and the Zimbra iCal plugin. This is bound to screw up my calendars at some point I'm sure...

Saturday, August 23, 2008

Update svn on Leopard to play nice with subclipse

Not so long ago I moved forward to STS 1.1 which is based on Eclipse 3.4 Ganymede. Of course I needed a svn plugin and then I ran into this issue.

Mac OSx packages an old version of collabnet subversion (1.4.x). And that doesn't play nice with subclipse. The fix suggested there is to use an old version because:

For Windows users, it is a simple matter of installing the new Subversion 1.5 client and making sure JavaHL is on the path. For Unix users, this workaround obviously defeats the purpose of having a distro with package management and requires manual installation of the libraries in the correct locations.

If you truly understand that and it is a blocking concern for you (notice the hint of sarcasm), don't read on. There is however a very simple solution to run the right version and just make it work.

  1. Download and install http://www.collab.net/downloads/apple/download.html
  2. sudo rm /usr/bin/svn* (you might want to check if you haven't got any other programs named svn* before you do this)
The second step is needed because the collabnet package installs simlinks into /usr/local/bin and the programs in /user/bin take precedence.

Once this is done you're good to go, and with the latest versions.

Update: I've moved on to do this with MacPorts, lately their svn versions are fine, and the installation is much simpler.

Wednesday, August 20, 2008

Correct Simple Singletons

This is going to be a very short blog. It's not about concurrency. It's about avoiding to think about concurrency. As was the original intent of this blog it is about being lazy, but still not being wrong.

Yesterday I read a very old blog while digging through the web for reasons to be scared of the volatile keyword. I found plenty, but this one is a gem: http://blogs.msdn.com/brada/archive/2004/05/12/volatile-and-memorybarrier.aspx. It's about .Net code, but the basic problems also apply in Java. The link to http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html is worth a read too.

If you can think about concurrency but you don't want to do it every day like me adhere to these rules when writing singletons:

When you plan on using the singleton write:

public class Singleton {
private static final instance = new Singleton();
private Singleton() {}
public static Singleton get() {
return instance;
}
}


When you don't plan on using the singleton, but you still feel the urge to implement it write:

public class Singleton {
private static instance;
private Singleton() {}
public static synchronized Singleton get() {
return instance;
}
}


When you're not going to use the singleton a lot, it is probably more memory efficient to just use a disposable instance, hence removing the need for the singleton at all. So the recipe goes like this:
  1. Don't use a singleton if you don't need to
  2. Use the simple (static final) variant if you do need a singleton
  3. Use the synchronized variant if you are intent on going on the downward slope
  4. Of course you are special, so go on and do it the hard way.

Wednesday, July 9, 2008

Don't repeat yourself, just quote yourself.

I just read an article by Dan North about how the DRY principle doesn't work with Test code. Obviously I agree with him, because it is almost trivial once you've figured it out on your own. I already met many people that did and were quite happy with themselves for it, actually that could have been me after I had about 1 year of experience with TDD.

When I read the linked blog I mused over the main counter argument against dropping DRY, it is actually the argument to adopt it: what about the maintenance hell of all that repeated code. Arguably if you use proper mocking or stubbing (especially mocking) you shouldn't have too much trouble with this, but wouldn't it be nice if there was a solution for this?

So what are the requirements:
  1. We want to get readable code (not requiring you to constantly switch source files or scroll)
  2. We want little writing effort (not repeating the same code snippet over and over)
Requirement 2. is covered by OO, AOP and friends, but they completely ruin 1. in certain scenarios (e.g. test code). To get 1. you will have to drop 2... NOT good enough!

I am a fan of wikis and as you might know many have a feature called templates that specifically targets these two requirements. How about template in code. Just add a template construct and let the IDE optionally show the actual code inline.

I like it.