gradle版本:4.1
maven版本:3.5.0
現象:
執行./gradlew publishMavenPublicationToMavenLocalRepository或publishMavenPublicationToMavenLocal2Repository
任務想發布到~/.m2下面,結果publish到工程當前目錄的~/.m2下面;而不是到系統的~/.m2下面;從而導致其他工程找不到publish到本地的版本;
解決方法:
修改系統的~/.m2/settings.xml(注意不是maven安裝目錄下的conf/settings.xml)的localRepository配置:
<localRepository>~/.m2/repository</localRepository>
改為
<localRepository>${user.home}/.m2/repository</localRepository>
分析解決過程:
跟蹤gradle源碼,分析MavenLocal的配置過程發現:
在DefaultBaseRepositoryFactory中:
public MavenArtifactRepository createMavenLocalRepository() { MavenArtifactRepository mavenRepository = (MavenArtifactRepository)this.instantiator.newInstance(DefaultMavenLocalArtifactRepository.class, new Object[]{this.fileResolver, this.transportFactory, this.locallyAvailableResourceFinder, this.instantiator, this.artifactFileStore, this.pomParser, this.createAuthenticationContainer(), this.moduleIdentifierFactory, this.fileResourceRepository}); File localMavenRepository = this.localMavenRepositoryLocator.getLocalMavenRepository(); mavenRepository.setUrl(localMavenRepository); return mavenRepository; }
說明MavenLocal的Repository地址由localMavenRepositoryLocator.getLocalMavenRepository()生成,而localMavenRepositoryLocator實際上是DefaultLocalMavenRepositoryLocator;
查看其源碼:
public File getLocalMavenRepository() throws CannotLocateLocalMavenRepositoryException { String localOverride = this.system.getProperty("maven.repo.local"); if (localOverride != null) { return new File(localOverride); } else { try { String repoPath = this.parseLocalRepoPathFromMavenSettings(); if (repoPath != null) { return new File(this.resolvePlaceholders(repoPath.trim())); } else { File defaultLocation = (new File(this.system.getProperty("user.home"), "/.m2/repository")).getAbsoluteFile(); LOGGER.debug("No local repository in Settings file defined. Using default path: {}", defaultLocation); return defaultLocation; } } catch (SettingsBuildingException var4) { throw new CannotLocateLocalMavenRepositoryException("Unable to parse local Maven settings.", var4); } } }
而配置路徑由parseLocalRepoPathFromMavenSettings生成:
private synchronized String parseLocalRepoPathFromMavenSettings() throws SettingsBuildingException { if (this.localRepoPathFromMavenSettings == null) { this.localRepoPathFromMavenSettings = this.settingsProvider.getLocalRepository(); } return this.localRepoPathFromMavenSettings; }
而settingsProvider實際上是DefaultMavenSettingsProvider:
public String getLocalRepository() { String localRepo = this.readLocalRepository(this.mavenFileLocations.getUserSettingsFile()); if (localRepo == null) { localRepo = this.readLocalRepository(this.mavenFileLocations.getGlobalSettingsFile()); } return localRepo; }
而mavenFileLocations實際上是DefaultMavenFileLocations:
public class DefaultMavenFileLocations implements MavenFileLocations { public DefaultMavenFileLocations() { } public File getUserMavenDir() { return new File(SystemProperties.getInstance().getUserHome(), ".m2"); } @Nullable public File getGlobalMavenDir() { String m2Home = System.getenv("M2_HOME"); return m2Home == null ? null : new File(m2Home); } public File getUserSettingsFile() { return new File(this.getUserMavenDir(), "settings.xml"); } @Nullable public File getGlobalSettingsFile() { File dir = this.getGlobalMavenDir(); return dir == null ? null : new File(dir, "conf/settings.xml"); } }
這里發現其對應配置就是~/.m2/settings.xml,對比maven安裝目錄下conf/settings.xml這個文件,發現用戶目錄不是用的~而是${user.home},因此懷疑這里的寫法存在兼容性問題,因此嘗試修改最終解決。
