Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to import Spring bean definition file using relative path

I am new to Spring and inherited a Spring project that had all the XML configuration in ProjectName/WebContent/WEB-INF/applicationContext.xml. I'm trying to break the configuration into different components so it is easier to substitute things like DataSources and Hibernate configuation when testing.

Here is my file structure:

ProjectName
  ->WebContent
      ->WEB-INF
          ->applicationContext.xml
          ->spring-datasource.xml
          ->spring-hibernate-properties.xml
          ->spring-persistence.xml
  ->test
      ->us.mn.k12... (Java pkgs with JUnit tests)
      ->spring-hsqldb-datasource.xml
      ->spring-test-bean-locations.xml
      ->spring-test-hibernate-properties.xml
  ->src
      ->us.mn.k12... (Java pkgs with production code)

In WEB-INF/applicationContext.xml, I import the following:

<import resource="spring-datasource.xml"/> <!-- Production datasource -->
<import resource="spring-hibernate-properties.xml"/> <!-- Production hibernate properties -->
<import resource="spring-persistence.xml"/> <!--  DAO's, hibernate .hbm.xml mapping files -->

The application works with the above configuration.

My JUnit tests run using DbUnit and an HSQLDB in-memory database. So my JUnit test references spring-test-bean-locations.xml, which has the following:

<import resource="spring-hsqldb-datasource.xml"/> <!-- HSQLDB datasource for test -->
<import resource="../WebContent/WEB-INF/spring-persistence.xml"/>  <!--  Production DAO's, hibernate .hbm.xml mapping files -->
<import resource="spring-test-hibernate-properties.xml"/> <!-- Hibernate properties for test -->

In this way, I can specify test datasource and hibernate properties, but reuse the production mapping file for the DAO's, etc. However, I get an error running my JUnit test. Here is the relevant part of the exception:

Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [../WebContent/WEB-INF/spring-persistence.xml]
Offending resource: class path resource [spring-test-bean-locations.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [../WebContent/WEB-INF/spring-persistence.xml]; nested exception is java.io.FileNotFoundException: class path resource [../WebContent/WEB-INF/spring-persistence.xml] cannot be opened because it does not exist

Now if I move spring-persistence.xml into /test so that I don't have to use the relative path, and reference it with <import resource="spring-persistence.xml"/>, then the tests run fine. So I think the contents of my XML files are OK, but I'm not properly importing with a relative path.

Is there anything obvious I'm doing wrong with my import of the relative path? And maybe the bigger question is does this look like a reasonable strategy for breaking applicationContext.xml into components to make it easier for testing?

Thanks!

like image 527
joeg3 Avatar asked Dec 21 '11 21:12

joeg3


2 Answers

The problem is: anything inside WEB-INF is not available to the ClassLoader in a regular project setup (and spring uses the ClassLoader by default to access resources). There are some hacks to work around this (like referencing the contexts using the file: prefix), but those are mostly ugly.

A better practice I'd suggest is to move the context files out of WEB-INF and into a dedicated resource directory (src/main/resources if you have a maven setup). That way they will be available to both the webapp ClassLoader and local unit test ClassLoaders.

Read the resources chapter to further understand the mechanisms involved.

like image 97
Sean Patrick Floyd Avatar answered Oct 15 '22 02:10

Sean Patrick Floyd


Use

 <import resource="file:**/WebContent/WEB-INF/spring-persistence.xml" />

It works in spring 3.2.1.RELEASE. Old versions I am not sure.

like image 21
PShetty Avatar answered Oct 15 '22 04:10

PShetty