All entries for Friday 03 February 2006
February 03, 2006
Interesting little problem upgrading to Spring 2.0M2 :)
Details here:
Essentially I upgraded my project from Spring 1.2.4 to Spring 2.0M2. Despite the addition of org.springframework.web.servlet.View#getContentType(); the upgrade appeared to be very smooth. The extensive unit tests passed, and all appeared to be well…..until I deployed it :)
14:50:36,676 ERROR [ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'siteBuilderDAO' defined in ServletContext
resource [/WEB-INF/persistence-context.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessio
nFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFact
ory' defined in ServletContext resource [/WEB-INF/persistence-context.xml]: Cannot create inner bean 'uk.ac.warwick.sbr.hibernate.
ClassFilteringLoadEventListener#159f498' while setting bean property 'eventListeners' with key [post-load]; nested exception is or
g.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uk.ac.warwick.sbr.hibernate.ClassFilteringLo
adEventListener#159f498' defined in ServletContext resource [/WEB-INF/persistence-context.xml]: Instantiation of bean failed; nest
ed exception is java.lang.IllegalStateException: BeanWrapper does not hold a bean instance
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext
resource [/WEB-INF/persistence-context.xml]: Cannot create inner bean 'uk.ac.warwick.sbr.hibernate.ClassFilteringLoadEventListener
#159f498' while setting bean property 'eventListeners' with key [post-load]; nested exception is org.springframework.beans.factory
.BeanCreationException: Error creating bean with name 'uk.ac.warwick.sbr.hibernate.ClassFilteringLoadEventListener#159f498' define
d in ServletContext resource [/WEB-INF/persistence-context.xml]: Instantiation of bean failed; nested exception is java.lang.Illeg
alStateException: BeanWrapper does not hold a bean instance
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uk.ac.warwick.sbr.hibernate.ClassFiltering
LoadEventListener#159f498' defined in ServletContext resource [/WEB-INF/persistence-context.xml]: Instantiation of bean failed; ne
sted exception is java.lang.IllegalStateException: BeanWrapper does not hold a bean instance
java.lang.IllegalStateException: BeanWrapper does not hold a bean instance
at org.springframework.util.Assert.state(Assert.java:341)
at org.springframework.beans.BeanWrapperImpl.getPropertyDescriptorInternal(BeanWrapperImpl.java:274)
at org.springframework.beans.BeanWrapperImpl.getPropertyType(BeanWrapperImpl.java:323)
at org.springframework.beans.PropertyEditorRegistrySupport.findCustomEditor(PropertyEditorRegistrySupport.java:233)
at org.springframework.beans.PropertyTypeConverter.doTypeConversionIfNecessary(PropertyTypeConverter.java:100)
at org.springframework.beans.PropertyTypeConverter.doTypeConversionIfNecessary(PropertyTypeConverter.java:73)
at org.springframework.beans.PropertyTypeConverter.convertToTypedMap(PropertyTypeConverter.java:277)
at org.springframework.beans.PropertyTypeConverter.doTypeConversionIfNecessary(PropertyTypeConverter.java:131)
at org.springframework.beans.BeanWrapperImpl.doTypeConversionIfNecessary(BeanWrapperImpl.java:853)
at org.springframework.beans.factory.support.AbstractBeanFactory.doTypeConversionIfNecessary(AbstractBeanFactory.java:672)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:370)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:126)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapabl
eBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFact
ory.java:368)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBeanDefinition(BeanDefinitionValueRes
olver.java:151)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolv
er.java:97)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.jav
a:235)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolv
er.java:118)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapabl
eBeanFactory.java:764)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFa
ctory.java:575)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFact
ory.java:405)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:238)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:148)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java
:186)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolv
er.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapabl
eBeanFactory.java:764)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFa
ctory.java:575)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFact
ory.java:405)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:238)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:148)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactor
y.java:253)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:331)
at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicat
ionContext.java:155)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:240)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:178)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
was thrown up. OK, I thought; lets look at the class in question (bear in mind this has all been working previously ;)):
The constructor looked like:
public ClassFilteringLoadEventListener(final Map> theListeners) {
}
}
And it was being wired up:
>bean class="uk.ac.warwick.sbr.hibernate.ClassFilteringLoadEventListener"<
>constructor-arg index="0"<
>map<
>entry key="uk.ac.warwick.sbr.linksgenerator.SiteNavigationContentFetcher"<
>list<
>bean class="uk.ac.warwick.sbr.hibernate.AutoWiringLoadedObjectListener"/<
>/list<
>/entry<
>/map<
>constructor-arg<
>/class<
Hmm, nothing strange there either (apart from me getting my < and > mixed up ;))
And then it occurred to me that Spring 2.0M2 understands generics :) Modifying the constructor argument to take a non typed Map fixed the problem.
Very subtle; took me most of the afternoon to catch this one ;)
JIRA is here: link
All this is redundant anyway because I found SWF (Spring Web Flow) PR5 uses a few classes which have been moved (PropertyEditorRegistrar etc.)
OK; I confess
Follow-up to The value of being explicit…. from Colin's blog
OK, OK: the original code actually used a Map instead of a Set.
For some reason I never used Set's; I would always use a Map and then Map.contains().
It is only in the last few years I started using a Set.
There, go and laugh now :)
I don't know; you just can get the senior staff nowadays :)
Come one; share the fun; what cringeworthy things do you do?
JDK5 Annotations; I love them, no, I hate them! (Actually I hate Eclipse) :)
So there is a fantastically useful annotation: @Override which when indicates that a particular method is overriding a method in the super class.
Why is this useful?
Assume today we are overriding the method called "methodA", tomorrow we get a new release of the library and the method in the parent class is no longer called "methodA", but renamed to "methodWithAMuchBetterName".
Your code is syntactically correct; it will compile, but it is not semantically correct. The no longer overridden method fails. No compiler errors to help you out; nothing.
You may argue that if you are overridding a method you almost certainly want to be calling super.sameMethod(); but that is just wrong. You do not have to , nothing in the million + 1 best practices suggest it, it is one of the more annoying anti-patterns. In particular; a lot of framework provide template method which do absolutely nothing for the sole purpose of you extending them; or they provide abstract methods for the same purpose.
Anyways; so JDK5 introduced an Annotation which told the compiler that the method is overridding a parent method. If the method in the super class is removed; your code won't compile.
Excellent. Lovely. As well as adding extra documentation to the source code; it has empowering side effects.
So sure; I love JDK annotations.
Now I implement an interface; create a method which implements the interface, stick an "@Override" on the method, and what happens? Eclipse moans that the method must override a superclass method.
ARRRGGHHH!!!!! It still compiles, but the source code looks like it is incorrect code.
Poo.
The value of being explicit….
So I had to explain some code I wrote a year or so ago to the colleague who was maintaing it and it looked something like this:
public CollaboratorA doSomething() {
final Set data = new HashSet();
// .. populate the data
return new CollaboratorA {
boolean isThisTrueForSomeCriteria(final Object o) {
return data.contains(o);
}
}
}
which is all perfectly valid; but not at all intuitive. In particular; what was the lifetime of Set data?
I then rewrote this and moved the inner class into it's explicit class:
public CollaboratorA doSomething() {
final Set data = new HashSet();
// .. populate the data
return new SetBackedCollaboratorA(data);
}
class SetBackedCollaboratorA implements CollaboratorA {
private final Set data;
SetBackedCollaboratorA(final Set theData) {
this.data = theData;
}
boolean isThisTrueForSomeCriteria(final Object o) {
return data.contains(o);
}
}
and this was found to be much easier to understand even though under the hood there is absolutely no difference. I am not entirely sure whether the byte code would even be any different, but the intuitiveness or readability was improved; so it was a win :)
To be clear; it was not the use an an inner class that was confusing; it was the fact that an inner class was referencing a variable defined in the method, outside of the method that created the inner class and the data.
Lesson for the day (because I keep needing to learn it again ;)); code that is functional is not as valuable as code that is intuitively functional.
Babies babies and more babies (well, only one ;))
So my wife and I am expecting my first child in the middle of May this year and we have been preparing the house for the grand arrival.
After redecorating and recarpeting the entire upstairs (which is not an easy job ; where do you put the contents of your entire upstairs???) we are now looking at purchasing the prerequisites for a sprog.
I have the following questions; how do manufacturers of baby stuff sleep at night; the prices are extortionate. Simply because most people would rather spend more "and be safe" then buy something cheaper; what a rip off. That being said; I am happy to spend the money because I want to be safe ;) :)
Anyways; the following questions:
– should I buy a travel system (which one) or stand alone car seats, buggies, carry cot etc. I anticipate having to purchase a new car seat in the next few years anyways.
– cot bed or just cot?
– where can I find a cot(bed), wardrobe, chest of drawers + baby changing thing that will comfortably fit in a 7ftx7ft room?
– what "essential" thing did you buy/wish you had bought/recommend I buy.
– recycleable nappies or conveient/chuck them away?
Both my wife and I are over 6ft and fairly strong, so weight of baby carrying things isn't so much an option, and we each have our own car with 5 doors, so dedicated baby seat will be fine. Anything we need to push should allow a large walking step though.
I will also be purchasing the following:
– sterilising thingy for the bottles (although we think breast is best, we still need them????)
– bottles (see above)
– millions and gazillions of nappies (see previous list)
– thousands of cloths that the baby will wear either once or twice with compulsory twiddly bits ;)
– video monitor (although which ones do not interface with the existing wireless network?)
anything else?
It is a very exciting time, and I cannot wait; but there is so much choice and it seems to me that buying the wrong thing would be a huge pain in the bum.
Ideas; comments; and don't even get me started on the names :)