1

I'm trying to migrate an existing big multi-module project from Maven 2 to Maven 3. The project does heavy use of profiles.xml to define settings for different environments (development, staging, production); and as you may know, profiles.xml is no more in Maven 3.

My intention is to make this transition as seamless as possible, so using settings.xml per machine is not an option, neither asking everyone to run maven with -s and a new settings file.

The parent pom is already quite extensive, since it configures plugins, repositories and dependencies for all modules; and it also uses a few profiles activated by OS to set proper classifiers on dependencies which are platform dependent. Therefore, I would rather not place all config options for all environments on the pom itself to avoid cluttering it.

I'm looking for a way to keep the environment configuration separate from the pom; yet common to all modules (present or future). Ideally, this means the solution requires just to edit the parent pom, and not the submodule's, making this issue transparent to all future submodules.

I've looked into properties-maven-plugin, but can't seem to get it to load the same file for all submodules, it looks for the file within the submodule itself, or if I define a relative path by using ${project.basedir}/../ it will fail for the parent project (since I can't define a build plugin in the super pom for the children, and not execute it on the parent too).

I've also looked into having separate property files per environment and setting a filter in the parent pom, but I run into the same issue.

So far the only thing I can get to work is editing all submodule's poms and manually setting the filter to ${project.basedir}/../config/${env}.property; but this certainly doesn't meet the criteria of being transparent to future modules and I find it very repetitive to have to set it on each and every submodule there is...

Any ideas are more than welcome, thanks in advance.

Johnco
  • 4,037
  • 4
  • 34
  • 43
  • Do you just want to share properties, or plugin config as well? – user944849 Dec 10 '14 at 15:08
  • Right now our parent pom configures plugins and dependencies; while our profiles have environment settings (connection strings, and such) used for filtering resources. I would like to keep both shared by all submodules, yet in separate files. – Johnco Dec 10 '14 at 16:11
  • It sounds like it is acceptable for the submodules to update the version of the parent POM they are using, yes? – user944849 Dec 10 '14 at 18:14
  • I'm not certain what you are suggesting, but feel free to submit your idea and I'll be grateful to analyze it. – Johnco Dec 10 '14 at 18:19

1 Answers1

0

You could try loading the config from a location on the web using Wagon and then reading that using the properties-maven-plugin:

<build>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>${org.apache.maven.wagon.version}</version>
        </extension>

        <!-- Needed by wagon-maven-plugin, see http://jira.codehaus.org/browse/MOJO-1821 -->
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-http</artifactId>
            <version>${org.apache.maven.wagon.version}</version>
        </extension>
    </extensions>
 .....
 <properties>
     <org.apache.maven.wagon.version>2.8</org.apache.maven.wagon.version>
     <shared.config.location>${project.build.directory}/external-config</shared.config.location>
 </properties>
 ....
 <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>wagon-maven-plugin</artifactId>
   <executions>
     <execution>
       <id>retrieve-config</id>
       <phase>initialize</phase>
       <goals>
         <goal>download</goal>
       </goals>
       <configuration>
         <!-- Does nothing if file not found -->
         <url>http://host.company.com/config/environments</url>
         <toDir>${shared.config.location}/environments</toDir>
         <!-- might need <includes> here too?? -->
       </configuration>
     </execution>
   </executions>
 </plugin>

Alternately, if you don't want to use Wagon, you can try the maven-remote-resources-plugin. Package the properties files a separate jar, then load them into a defined location as defined in this answer. The Wagon method is better if you want to make property changes that apply to everyone right away without them having to update a parent POM version.

In either case, once the resources are in the project's target directory you may use the properties-maven-plugin to load them. You could put either the Wagon or remote-resources style of this config in the new parent POM.

 <!-- Load the properties into the current maven build for use in property 
      replacements. Only impacts plugins running after this one -->
 <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>properties-maven-plugin</artifactId>
   <executions>
     <execution>
       <id>load-props</id>
       <phase>generate-sources</phase>
       <goals>
         <goal>read-project-properties</goal>
       </goals>
       <configuration>
         <files>
           <file>${shared.config.location}/environments/${your.target.env}.properties</file>
         </files>
         <quiet>true</quiet>
       </configuration>
     </execution>
  </executions>
</plugin>

The downside is that each existing module would have to update to use the new version of the parent POM to get the new functionality. There are some upsides to this downside though - you can convert to Maven 3 project by project as schedules allow, and you'll be able to do a quick SCM search to find out which projects haven't updated simply by noting which ones are using the old parent POM.

Community
  • 1
  • 1
user944849
  • 14,524
  • 2
  • 61
  • 83
  • Thanks for the advice! I'm a little concerned though of having to store configuaration on a completely different location rather than the same multi-module project & repository; it kind of breaks my intention of keeping everything as much as it was as possible... – Johnco Dec 11 '14 at 04:21
  • If you use the remote-resources method the environment configuration properties can be just another one of the modules in the existing multi-module build. We use the Wagon method to supply configuration globally - many multi-module projects across our organization. The remote-resources version works well also. – user944849 Dec 11 '14 at 13:50