Robert Munteanu
Robert Munteanu

Reputation: 68328

Varying plugin configuration for each child module

I have a multi-module build which contains modules which can target either Java 5 or Java 6. I want to allow modules to opt-in to Java 6, and leaving the default to 5.

To set Java 5 as a target I need to configure the following:

To set Java 6 as a target I need to configure the following:

I considered having two properties: java.compiler.source and osgi.bree which can be defined by each module, but this leaves place for error.

How can I override the configuration of these two plugins per module with a single switch?

Upvotes: 2

Views: 396

Answers (3)

yorkw
yorkw

Reputation: 41126

I don't think there is an elegant Maven way to solve this complex scenario, neither yours or Duncan's proposed solution are easy maintainable IMO, when number of sub module becomes tremendous.

For maximum maintainability, I would write shell script (and/or batch file on Windows) in case Maven can't do the job very well, for example, a set-version.sh (and set-version.bat) that loop all sub module and reset the default java.compiler.source and osgi.bree properties based on a version-feed.txt, the version-feed.txt gives you a single central place for manipulating your version varying. As you can see, the cons is this is really not a Maven solution, it requires running set-version.sh before mvn ... every time version customization is required.

In addition, For build/release standardization, I would use maven-enforcer-plugin to play/pause the build process based on a property version.set(which is flagged by set-version.sh) and prompt some warning/error message if developer is not follow the correct procedure when doing build. The version.set also gives the flexibility if you prefer to use the default values defined in every sub module, instead of running set-version.sh, just directly set it to true in the parent pom.xml or from command-line parameter.

Sample directory structure:

parent/
    module-a/
    module-b/
    module-c/
    ... ...
    pom.xml
    set-version.sh
    set-version.bat
    version-feed.txt

Hope this make sense.

Upvotes: 2

matts
matts

Reputation: 6897

How about allowing child modules to set a my.java.version property (or whatever you want it named) and embedding a Groovy script that sets version properties for the compiler and bundle plugins? Something like this in the parent pom:

<project ...>
    ...
    <properties>
        <my.java.version>1.5</my.java.version>     <!-- default Java version -->
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.groovy.maven</groupId>
                <artifactId>gmaven-plugin</artifactId>
                <version>1.0</version>
                <executions>
                    <execution>
                        <!-- set up properties in an early lifecycle phase -->
                        <phase>initialize</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <!-- this can be as simple or complex as you need it to be -->
                            <source>
                                if (project.properties['my.java.version'] == '1.6') {
                                    project.properties['my.compiler.version'] = '1.6'
                                    project.properties['my.execution.environment.version'] = 'JavaSE-1.6'
                                }
                                else {
                                    project.properties['my.compiler.version'] = '1.5'
                                    project.properties['my.execution.environment.version'] = 'J2SE-1.5'
                                }
                            </source>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <!-- now use the properties from above in the plugin configurations -->
        <!-- assume that both of these plugins will execute in a phase later than 'initialize' -->
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>${my.compiler.version}</source>
                        <target>${my.compiler.version}</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <configuration>
                        <!-- sorry if this part isn't correct; never used this plugin before -->
                        <instructions>
                            <Bundle-RuntimeExecutionEnvironment>${my.execution.environment.version}</Bundle-RuntimeExecutionEnvironment>
                        </instructions>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

Upvotes: 2

Duncan Jones
Duncan Jones

Reputation: 69409

I would personally structure your project so that Java 5 modules descend from one parent POM and Java 6 modules from another parent POM.

Global Parent (majority of global settings)
  Java5 parent (just define source/bundle)
    module A
    module B
  Java 6 parent (just define source/bundle)
    module C

Upvotes: 3

Related Questions