views:

1306

answers:

2

I have a Java Spring project, configured with Maven. As the amount of unit tests and their configuration files is adding up rapidly, I'm trying to centralize the test configurations to one properties file (the same one, which is used in building the project).

The unit tests are located (relative to the project path, of course) in tree

src/test/java/com (...)

The resource files for those tests are in

src/test/resources(...)

And lastly, the properties file, which the resource file should read, is in directory

src/main/filters

Now, I have a Junit class where I specify the configuration file location like this:


@ContextConfiguration(locations = { "classpath:com/initrode/quartz/SyncManagerJobTest-context.xml"})

In the configuration file SyncManagerJobTest-context.xml there is a line


<context:property-placeholder location="/src/main/filters/deploy.local.properties"/>

This results in the properties file to be read from directory . What I'd like to read is the properties file, which is located under src/main/filters. I tried using ../../ to traverse the directory upwards, but that didn't help. Using classpath: didn't work out either. I could use an absolute path with "file:", but that would require every developer in the project to modify the configuration, which is not good either.

To summarize, the question is: how can I force the configuration file in src/test/resources/ to read the properties file in src/main/filters?

And a related bonus question: when handling files in Java environment, are there other modifiers than "file:" and "classpath:"?

+4  A: 

If you specify src/main/filters as a resources location, Maven will move the resources to target/classes, and also compile the classes to the same location during the build. You then do not have a relative path to deal with as they have the same root. If you don't do something like this, your filters directory will not be included in the build.

Update: Of course your test code is output to target/test-classes, so to simplify the testing, you could specify that src/main/filters is copied to target/test-classes during the process-test-resources phase. I've modified the example to show that behaviour.

If you have not already done so, you can use the build-helper-maven-plugin to add the filters folder as a resource location.

The configuration to do so looks like this:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.3</version>
  <executions>
    <execution>
      <id>add-resource</id>
      <phase>process-test-sources</phase>
      <goals>
        <goal>add-test-resource</goal>
      </goals>
      <configuration>
        <resources>
          <resource>
            <directory>scr/main/filters</directory>
          </resource>
        </resources>
      </configuration>
    </execution> 
  </executions>
</plugin>
Rich Seller
+3  A: 

To me, it sounds a bit strange to put a properties file in src/main/filters if you don't plan to use this file as... a filter. If this file is used as a standard test resource, why don't you place it in src/test/resources? If you want to filter some resources files, why don't you just do it and use the filtered resources? I would expect to see something like:

<build>
  <!-- Filter resources -->
  <filters>
    <filter>src/main/filters/my-filter.properties</filter>
  </filters>
  <!-- Resources for src/main -->
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource> 
  </resources>
  <!-- Resources for src/test -->
  <testResources>
    <testResource>
      <directory>src/test/resources</directory>
      <filtering>true</filtering>
    </testResource>
  </testResources>
</build>

I may be missing something but I think you are mixing some concepts. In your case (and if I understood correctly what you are trying to do), I'd use maven profiles and filters to manage multiple environments deployment. Have a look at:

Pascal Thivent
The location of the properties file is probably not the best one, but as I'm working on an existing project, I'll just leave it be..We have three different properties for different production environments. When developing the application, there are many properties to be configured, db, ldap and so on. Having two resource locations would mean having to maintain two properties files, which I consider not to be ideal.Thanks for the links, I'll check them.
simon
I'm not sure to understand what you mean by "having two resource locations" and this is not a requirement anyway. But, if you have different production environments, don't you have to manage different for each environments? This is what the links are about (in a maven way).
Pascal Thivent
@Pascal this is a good point (+1), but from the other parts of the question I think the OP may not mean filter in the Maven sense. So the files should probably go in src/main/resources. When working with an existing project structure though this may not be possible, hence my workaround
Rich Seller
@Rich I think you are right. I just wanted to point out the maven way, just in case.
Pascal Thivent