As mentioned I stumbled over a few things while writing my first NamespaceHandler for Spring.

My very first experiments looked as if Spring simply was ignoring my namespace and I ended up having the XML parser complain about not finding my schema definition. It seemed to be some kind of infrastructural problem and not a code problem, so I tried to get the simple dateformat example from the docs working.

Unfortunately the example doesn't work without changes since the four different places you have to specify the XML Namespace URI or XSD location use two different root URIs (http://www.mycompany.com/schema/myns and http://www.springframework.org/schema/myns). Bug reported.

After some futzing around I realized that my XSD file wasn't ending up on Spring's CLASSPATH and thus Spring didn't find it. I would have expected Spring to complain if I specify a location mapping in META-INF/spring.schemas that it cannot resolve. Unfortunately it fails silently.

Writing the NamespaceHandler is really simple, as is writing a BeanDefinitionParser, at least if you don't need to do fancy things.

Not being familiar with Spring's internals I kept looking around the BeanDefinitionBuilder class for a way to provide an id for the bean under construction. Maybe I should have looked closer or the documentation isn't that obvious. If you extend AbstractBeanDefinitionParser (maybe indirectly) you set the bean's id by overriding resolveId.

Up to here I was extending AbstractSingleBeanDefinitionParser because it did all the things I needed.

Next step: I want to define a bean that has a parent bean. Searching through BeanDefinitionBuilder's API docs lead to the childBeanDefinition factory method, which clearly is the way to go. Unfortunately AbstractSingleBeanDefinitionParser hasn't been designed for my use case so I ended up writing my own AbstractBeanDefinitionParser subclass that is almost identical to AbstractSingleBeanDefinitionParser but adds another protected getParentName(Element) method that will lead to the creation of a child bean if it returns non-null (and neither getBeanClass nor getBeanClassName return non-null).

If anybody is interested in the code, you can find it here - Apache License 2.0.

path: /en/Java/Spring | #

In Spring you can have ApplicationContexts form a hierarchy, one contexts is said to be the parent of another one. There isn't much documentation about what this means in practice. Basically it means "if you ask the child context for a bean and it doesn't have a definition for it, it will consult its parent context". But how does this extend to abstract beans or dependencies?

What I want to achieve is that I define a concrete implementation of a bean in the parent context and allow the child context to override some of its settings. My preference would be an option where the child context cannot change the class backing the bean and where I can restrict the properties the child context is allowed to override to a certain set, this is what I tried:

  <beans ...>
    <!-- parent -->
    <bean id="abstractHello" abstract="true">
      <property name="message" value="inside parent context"/>
    </bean>

    <bean id="concreteHello" parent="abstractHello"
          class="springtests.Hello" scope="prototype"/>
  </beans>

  <beans ...>
    <!-- child -->
    <bean id="abstractHello" abstract="true">
      <property name="message" value="inside child context"/>
    </bean>
  </beans>

with a simple bean that has a setter for a String "message" property. Unfortunately this doesn't work as I hoped, "concreteHello" retrieved from the child context has a message of "inside parent context".

So what about dependencies instead of inheritance? I introduce a simple "holder" object and inject it into my bean:

  <beans ...>
    <!-- parent -->
    <bean id="holder" class="springtests.MessageHolder">
      <property name="message" value="inside parent context"/>
    </bean>

    <bean id="helloFromHolder" class="springtests.Hello" scope="prototype">
      <property name="messageHolder" ref="holder"/>
    </bean>
  </beans>

  <beans ...>
    <!-- child -->
    <bean id="holder" class="springtests.MessageHolder">
      <property name="message" value="inside child context"/>
    </bean>
  </beans>

Which leads to the same result. When "helloFromHolder" gets configured, it won't see the "holder" reference of the child context.

To be honest, the behavior I've seen is what I had expected, but I thought I could try anyway.

I settled with allowing the child context to completely override the parent bean. But I wrote my own NamespaceHandler code (and bumped into a bunch of gotchas for another post) which prevents setting of properties that shouldn't be overridden and doesn't allow setting the class. Something like

  <beans ...>
    <!-- parent -->
    <bean id="abstractHello" class="springtests.Hello" abstract="true">
      <property name="message" value="inside parent context"/>
    </bean>

    <bean id="hello" parent="abstractHello"/>
  </beans>

  <beans ...>
    <!-- child -->
    <override:hello>
      <override:message>inside child context</override:message>
    </override:hello>
  </beans>

Here the "abstractHello" bean provides the class and default parameters and the NamespaceHandler doesn't allow setting id (it will always be "hello"), parent (always abstractHello), class or any of the other attributes that might be available. Unfortunately I can't prevent the child context from using "plain" Spring bean definitions to completely override "hello".

path: /en/Java/Spring | #

For some reason the Sun engineers decided it would be a good idea to base the XSLT engine of JDK 1.5 on Apache Xalan XSLTC. I'm not familiar enough with Xalan-J development to know whether XSLTC seemed to be stable back then or whether it would be a good choice today, but I do know that the specific version used is buggy. Too buggy to use in any environment.

We've had out share of XSLTC related bug reports in Ant (like this one) and it completely breaks XPath assertions in XMLUnit prior to 1.1 because it chokes on this trivial stylesheet:

<xsl:stylesheet ...>
  <xsl:preserve-space elements="*"/>
  <xsl:output method="xml" version="1.0" encoding="UTF-8"/>
  <xsl:template match="/">
    <xpathResult>
      <xsl:apply-templates select="XPATH_EXPRESSION" mode="result"/>
    </xpathResult>
  </xsl:template>
  <xsl:template match="*" mode="result">
    <xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>

which is used by SimpleXPathEngine to get the result of selecting XPATH_EXPRESSION from a document.

And now it strikes again in XMLUnit see this bug report or current Gump builds until I get around fixing it. XMLUnit uses an even simpler stylesheet to get rid of element content whitespace if you ask it to:

<xsl:stylesheet ...>
  <xsl:output method="xml" version="1.0" indent="no"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="/"><xsl:copy-of select="."/></xsl:template>
</xsl:stylesheet>

This fails to strip element content whitespace if you use XML namespaces in your documents.

A bug in XSLTC that has been fixed in December 2005 and has been reported to Sun in April 2006 is still alive - at least in Update 11 of Java 5 which is what you get on Ubuntu, I haven't checked update 12, yet.

Back to thinking about a workaround for this issue, other than telling people to use Xalan-J or GNU JAXP or any other working implementation instead.

Of course it works for any version of JDK 1.4 or 1.6.

path: /en/oss/XMLUnit | #

If you allow them to sleep in your bed they will spread until they occupy the available space completely.

path: /en/ramblings | #