Wednesday, January 4, 2012

Spring bean definition profiles and web.xml

Spring 3.1 was released a few weeks ago. One of the interesting new features is the first-class support for bean definition profiles: you can define beans as part of a profile and than activate that profile if required. Bean definitions that are part of a profile that has not been activated are simply skipped.

Last week, I spent a few days upgrading our application to Spring 3.1 and updating it to make use of bean definition profiles. As most other sizable Spring based apps, we had devised our own configuration switching system based on a combination of Maven resource filtering and XML <import/> elements containing ${placeholders}. This works well enough but it would obviously be better to directly use the bean definition profile feature of Spring 3.1, if only because it's better documented.

By default, the list of active bean definition profiles will be determined by looking at a spring.profiles.active property. Out-of-the-box, a Spring WebApplicationContext will setup a PropertySources list containing the servlet config parameters, servlet context parameters, JNDI properties, system properties and environment variables, in that order. This implies that you can define the spring.profiles.active property in any of those locations, the most obvious one being servlet context parameters in web.xml:
<context-param>
 <param-name>spring.profiles.active</param-name>
 <param-value>foo-profile, bar-profile</param-value>
</context-param>
We wanted to use Maven profiles to switch between Spring bean definition profiles, so the initial idea was to simply do Maven resource filtering on web.xml:
<context-param>
 <param-name>spring.profiles.active</param-name>
 <param-value>${spring.profiles.active}</param-value>
</context-param>
It turns out doing resource filtering on web.xml leads you to a world of pain:
  • The Jetty plugin for Maven assumes the web.xml is static and simply uses the one in the source folder. You can explicitly tell it to use the web.xml from the target folder (using the <webXml> config element), but that results in other problem: by default resource filtering does not process the src/main/webapp directory. Of course you can specify filtering for that directory in your POM, but that again given problems: the Maven war plugin will overwrite the filtered web.xml with a copy from the source folder while packaging the web application. You can fix this by adding a <webResources> definition to your POM for the war plugin. Clearly this situation is far from ideal: it's complex and requires an explicit mvn package just to be able to do mvn jetty:run.
  • Idem ditto for Tomcat.
  • Eclipse WTP also directly uses the web.xml from the sources folder. Maybe there are ways around this, but I have no idea how that would work.

In the end we decided to forgo Maven resource filtering on web.xml and simply use an application specific properties file:
spring.profiles.active=${spring.profiles.active}
To get Spring to pick up this additional properties file, we simply add a property source to the application context using an ApplicationContextInitializer:
public class MyAppCtxInitializer
  implements ApplicationContextInitializer<ConfigurableApplicationContext> {
 public void initialize(ConfigurableApplicationContext applicationContext) {
  try {
   applicationContext.getEnvironment().getPropertySources()
     .addLast(new ResourcePropertySource("classpath:/myapp.properties"));
  } catch (IOException e) {
   // properties file cannot be found: ignore and just continue without these properties
   logger.info("Unable to load fallback properties: " + e.getMessage());
  }
 }
}

This approach avoids all the downsides of doing filtering on web.xml (web.xml is now completely static and mvn package no longer required). The only negative aspect is that it introduced an application specific properties file instead of simply relying on standard Spring conventions.

Sunday, December 25, 2011

Good code and good wine

I've discussed the "What is good code?" question before. This is such a broad topic that people come up with all kinds of interesting analogies to describe beneficial traits of good code. For instance, Uncle Bob often compares good code to a good book: it's important to have a good story (design/architecture), introduce key characters (concepts) at appropriate times and so on. Another interesting analogy that I've heard is that good code is like a leather glove: over time it becomes more flexible in areas where it needs to be flexible and more rigid in places that need more rigidity, exactly the way good code should behave and evolve (I'm not sure where I first heard this analogy and who I should credit for it).

Another analogy I (? -- I've never heard it before so I'll be so bold as to take credit myself) came up with recently is comparing good code with good wine. An important characteristic of good wine, maybe even the most important one, is that it tastes good. Likewise, good code needs to function properly and deliver the required functionality. However, as wine aficionados will tell you, tasting good is not the only important trait of a good wine: great wine also has things like an interesting texture, a complex taste palette and so on (not being a wine connaisseur myself, I won't dwell on it). Similarly, having a functional program doesn't imply good source code. Good code needs to exhibit extra characteristics such as flexibility, testability, adhering to the principle of least astonishment and so on.

I'd love to hear about more analogies used to describe good code!

Thursday, November 24, 2011

JDK8 and the future of JVM based languages

Last week at Devoxx 2011 I attended a number of sessions covering new JVM based programming languages such as Kotlin and Ceylon. Of course there were also a number of sessions talking about the usual suspects: Groovy, Scala and JRuby.

There were also a considerable amount of talks covering JDK8 and how that's shaping up. I got the strong impression that Oracle certainly doesn't want to see JDK8 turn into another multi-year debacle. Progress on JDK8 (vitual extension functions, closures, ...) seems impressive and I got a real sense of direction and focus from those involved.

I've been following the whole other languages on the JVM movement that has been going on the last couple of years with interest, but mostly as a by-stander: I'm not a hard-core, opinionated programming language expert like some. However, if I look at the input I gathered at Devoxx I can't help but make a few observations:
  • Although some of the new JVM languages have interesting ideas and are definately a step up from Java, they didn't trigger that aha-erlebnis I had when I first started using Java 1.02 after having used C.
  • The infectuation with dynamic typing seems to be largely over: everybody is back in agreement that strong static typing is the way to go.
  • Scale can't get any love and seems destined to remain an interesting language experiment.
  • Oracle is on somewhat of a mission to deliver JDK8 sooner rather than later.
All of this makes me wonder if Java's successor will actually be Java itself, but in it's 8th incarnation, and whether or not Java 8 will effectively blow all new contenders out of the water? I'm looking forward to seeing how this unfolds!

Friday, October 28, 2011

Java puzzler

Take a look at the following piece of code:
package test;

import java.util.Date;

public class Test {

 public static String format(Date date) {
  return String.valueOf(date);
 }

 public static String format(long millis) {
  return format(new Date(millis));
 }

 public static String format(Instant instant) {
  return format(instant == null ? null : instant.getMillis());
 }

 public static class Instant {

  private long millis;

  public Instant(long millis) {
   this.millis = millis;
  }

  public long getMillis() {
   return millis;
  }
 }

 public static void main(String[] args) {
  Instant instant = null;
  format(instant);
 }
}
Any idea what the output will be? Turns out this throws a NullPointerException:
Exception in thread "main" java.lang.NullPointerException
 at test.Test.format(Test.java:16)
 at test.Test.main(Test.java:34)
Interesting. Line 16 is clearly fishy: The idea is that if the instant is null, the format(Date) method should be called, while format(long) should be called otherwise. It turns out things are much more contrived at the bytecode level (use javap -c):
public static java.lang.String format(test.Test$Instant);
  Code:
   0: aload_0
   1: ifnonnull 8
   4: aconst_null
   5: goto 15
   8: aload_0
   9: invokevirtual #35; //Method test/Test$Instant.getMillis:()J
   12: invokestatic #41; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
   15: invokevirtual #46; //Method java/lang/Long.longValue:()J
   18: invokestatic #49; //Method format:(J)Ljava/lang/String;
   21: areturn
This actually translates to the following Java code, which clearly explains the NullPointerException:
public static String format(Instant instant) {
 return format((instant != null ? Long.valueOf(instant.getMillis()) : null).longValue());
}
Sometimes autoboxing can really rear its ugly head!

Sunday, September 4, 2011

Surprise of the day

Well what do you know! It turns out Microsoft was a bigger contributor to Linux kernel version 3.0 than Canonical, as LWN reports. Probably a bit of a fluke but an interesting statistic nonetheless!

Saturday, July 23, 2011

Q_rsqrt

I still remember encountering the following piece of code while browsing through the Quake 3 source code back in 2005:
float Q_rsqrt( float number )
{
  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &y;  // evil floating point bit level hacking
  i  = 0x5f3759df - ( i >> 1 ); // what the fuck?
  y  = * ( float * ) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
  // y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed

  #ifndef Q3_VM
  #ifdef __linux__
    assert( !isnan(y) ); // bk010122 - FPE?
  #endif
  #endif
  return y;
}
That comment on line 10 pretty much sums it up: WTF!?!?

I again ran across this piece of code while browsing an amuzing list of the best comments in source code you've encountered, over on Stackoverflow. It turns out the original author of this illustrious piece of code is still unknown (it's not John Carmack as you might have assumed). A nice write-up of the likely history of this hack can be found on Beyond3D. Interesting reading for sure!
UPDATE: The original author is actually known and it is Greg Walsh. Wikipedia also has a lot of background.

Talking about funny comments in code, my personal favorite from the Stackoverflow list must be the following:
stop(); // Hammertime!
Not so much the comment, but the german version really cracked me up!

Tuesday, July 19, 2011

Java SE 7

It was a long time in the making but all JSRs constituting Java SE 7 have crossed the finish line! The actual Java SE 7 software release is just around the corner (July 28th). Exciting stuff!