Search code examples
mavendependenciesmaven-profiles

Is it possible to use a maven property to activate a profile based upon a file?


I would like to download the JACOB dlls when they're not in my local repository.

As a consequence, I have those two profiles

    <profile>
        <id>use-jacob-dll</id>
        <activation>
            <file>
                <exists>${settings.localRepository}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</exists>
            </file>
        </activation>
        <dependencies>
            <dependency>
                <groupId>${jacob.groupId}</groupId>
                <artifactId>jacob</artifactId>
                <type>dll</type>
                <classifier>x64</classifier>
                <version>${jacob.version}</version>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>download-jacob-dll</id>
        <activation>
            <file>
                <missing>${settings.localRepository}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</missing>
            </file>
        </activation>

But, even when download-jacob-dll has accomplished its goal, a call to mvn help:active-profiles indicates the following

The following profiles are active:

 - tests-for-eclipse (source: com.capgemini.admdt:kpitv:1.2.4-SNAPSHOT)
 - download-jacob-dll (source: com.capgemini.admdt:kpitv:1.2.4-SNAPSHOT)

I suspect it is due to the fact that I use the ${settings.localRepository} in my activation property.

Question: Is it the cause of the failure? And if so, how can I activate my profile only when dependency is missing ?


Solution

  • Is it possible to use a maven property to activate a profile based upon a file?

    No, as stated by the Maven documentation on profiles

    Supported variables are system properties like ${user.home} and environment variables like ${env.HOME}. Please note that properties and values defined in the POM itself are not available for interpolation here, e.g. the above example activator cannot use ${project.build.directory} but needs to hard-code the path target.

    However, from the POM documentation we also get that

    a given filename may activate the profile by the existence of a file, or if it is missing. NOTE: interpolation for this element is limited to ${basedir}, System properties and request properties.

    Hence, indeed no Maven properties except ${basedir} are allowed.


    And if so, how can I activate my profile only when dependency is missing?

    By hardcoded path to the dependency or concerned file would be a solution, even though not portable like the solution you meant.

    Alternatively you could use a request property as mentioned by the documentation above, thus need to configure the activation with a property which then must be passed from the command line (more portable but more fragile as well):

    <activation>
        <file>
            <missing>${path}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</missing>
        </file>
    </activation>
    

    Then invoke maven as following:

    mvn clean install -Dpath=path_to_local_rep
    

    The solution above could be reasonable in some contexts like Jenkins jobs.