views:

89

answers:

4

I have a new web app that is packaged as a WAR as part of a multi-module Maven project. The applicationContext.xml for this WAR references beans that are imported from the "service" module, which in turn imports beans from the "dao" module. The import statement in applicationContext.xml looks like this:

<import resource="classpath*:service.xml" />

and the one inside the service.xml file looks like this:

<import resource="classpath*:dao.xml" />

Neither Spring STS, nor Eclipse show any warnings or errors in my bean files. I reference the imported beans all over the place. The Maven build works fine and the DAO integration tests all pass (they use the beans). I don't have any service integration tests yet.

But when I start up the WAR in Jetty I get an error:

Error creating bean with name 'securityService' 
Cannot resolve reference to bean 'userDAO' while setting constructor argument

All of the imported bean XML files can be found inside their respective JAR files in the WEB-INF/lib directory. Indeed, the service bean that threw the error is itself defined inside the service.xml file inside the service module's JAR file.

Apparently the service module can't find the bean that it imported from the dao module. Obviously I don't understand something...seems like this should this Just Work?

+1  A: 

It should be like

<import resource="classpath:service.xml"/>
org.life.java
If I do this then Spring STS, Eclipse both warn about undefined beans and the build fails the integration tests because of undefined beans.
HDave
@Hdave sorry i misplaced that , updated the ans.
org.life.java
No problem. Thanks for the help. Unfortunately, I still have the same problem. However, Spring STS, Eclipse, and the Maven don't seem to mind the missing asterisk!
HDave
@HDave what is your dependency structure is your xml file directly in the jar which is in the class path ?
org.life.java
Yes. The service.xml is in service.jar which is in the WEB-INF/lib. It references persist.xml which is in persist.jar which is in the WEB-INF/lib as well. It's almost like Spring has a bug regarding transitive imports....
HDave
+1  A: 

The difference between the classpath:thingy.xml and classpath*:thingy.xml notation is that the former uses the standard classpath mechanism to resolve one resource (using ClassLoader.getResource(name)), whereas the latter will use ClassLoader.getResources(name) to retrieve all matching resources on the classpath, a distinction that should be irrelevant in your situation as I guess there is only one dao.xml file on the class path.

I think your problem is different, you are missing a leading slash.

Use this for a single resource

<import resource="classpath:/dao.xml" />

and this for multiple resources

<import resource="classpath*:/dao.xml" />

See

seanizer
Good know about the asterisk, thanks for the links. Putting the leading slash it has had no effect, however.
HDave
Did you verify that the xml files are actually in the jars?
seanizer
Yes. I opened the war, then found the jars, then opened the jars and found the xml files, and then opened the xml files and found the beans.
HDave
Then I guess you'll have to debug the bean definition parser. Put a BreakPoint in org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(Element)
seanizer
Before I set the BreakPoint, I decided to enabled DEBUG logging. Within the log I found a hint and followed it to the root cause. See answer....
HDave
A: 

Are you having multiple applicationContexts and possibly the parent context is referring to a bean defined in the child context?

Raghuram
To the best of me knowledge I have only the one applicationContext and all beans should be in that one context.
HDave
A: 

I enabled DEBUG logging for 'org.springframework' in order to see if I could learn anything. What I found were messages to the effect that the DAO beans had been created, but there was also a message about them having no name or id.

I check the file, and they all did have an id. So what was it? I check the XML namespace and saw:

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"

and noticed it was old (I am using Spring 3.0.2) and changed it to:

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

Once I changed it, Spring instantly threw half a dozen errors regarding beans that were defined incorrectly (but never used apparently). Once I fixed those errors, everything Just Worked. I've since gone through the entire system checking Spring XML file namespace versions.

Thanks to all for the help. Can't believe I wasted a day on this stupidity!!

HDave
*Can't believe I wasted a day on this stupidity* That won't be the last time. In my experience, building great functionality takes a lot less time than tracking down stupid innocent-looking bugs.
seanizer