Maven plugin fails to resolve '${user.home}' in settings.xml, hence gets local Maven repo location wrong on 'install'

The Maven plugin fails the install task with the following message:

Execution failed for task ':install'.
> Could not publish configuration 'archives'
   > Error installing artifact 'lucene-learning:common:jar': Error installing artifact: /Repositories/maven/lucene-learning/common/1.0/common-1.0.jar (No such file or directory)

The path it is trying to go to does not exist. Apparently, it is ignoring the local repo in my settings.xml. It is also ignoring the following which I’ve put in the build file, though I shouldn’t need to.

uploadArchives {
    repositories {
        mavenDeployer {
         repository(url: "file://Users/Abhijit/Repositories/maven")
        }
    }
}

For the ‘install’ task, you’ll have to configure ‘mavenInstaller’ rather than ‘mavenDeployer’. A local repo location specified in ‘~/.m2/settings.xml’ (not ‘settings.xml’ in the Maven install dir) will be honored. I’m not entirely sure what the error message is complaining about; a full stack trace (as a Github Gist) might help.

I turns out that the settings.xml defines localRepository as below:

<localRepository>${user.home}/Repositories/maven</localRepository>

This is perfectly valid for Maven. However, Gradle couldn’t resolve ${user.home} variable and was ignoring that. It was even ignoring the repo defined in the uploadArchives block. This gotta be a bug.

As I said, a ‘mavenDeployer’ repo declaration will only affect ‘upload’ but not ‘install’. System properties in the local repo location used to be supported, but may not be supported anymore.

Sorry, I deleted my comment and wanted to add that to the original post instead. However, you’d posted in the meantime so original post couldn’t be edited. Adding my comment back again so that people visiting this thread know what the issue is.

I turns out that the settings.xml defines localRepository as below:

<localRepository>${user.home}/Repositories/maven</localRepository>

This is perfectly valid for Maven. However, Gradle couldn’t resolve ${user.home} variable and was ignoring that.

Peter, can you please provide a sample code of how to configure the mavenInstaller? Also, other tasks are resolving user.home just fine, why wouldn’t install task?

Just use ‘mavenInstaller’ instead of ‘mavenDeployer’. Not sure what you mean by “other tasks are resolving user.home fine”. It’s about supporting the Maven expression language used in pom.xml and settings.xml.

This fails so apparently it’s slightly more involved than just replacing mavenDeployer with mavenInstaller. The Maven plugin page doesn’t have any indication of how to configure a mavenInstaller.

install {
    repositories {
     mavenInstaller {
       repository(url: "file:///Users/Abhijit/Repositories/maven")
     }
    }
}
* What went wrong:
A problem occurred evaluating root project 'common'.
> Could not find method repository() for arguments [{url=file:///Users/Abhijit/Repositories/maven}] on repository container.

What I meant by “other tasks are resolving user.home” is that Maven plugin in general does not have a problem finding the local repo and downloading from it. It’s only the install task that fails.

The book “Building and Testing with Gradle” states in chapter 4, section “Installing to the Local Maven Repository” that “This install process, equivalent to mvn install, is guaranteed to be compatible with Maven because it actually uses the Maven Ant Tasks produced by the Maven team and hosted at Apache.”.

If this is not a contradiction, I don’t know what is.

maven-publish plugin handles ${user.home} variable just fine, why can’t the maven plugin do that? This should be a bug.

Can we have a JIRA on this please?

It’s a limitation or, if you will, bug. Not more, not less.

OK, glad we agree. Thanks for opening the JIRA.