如何让Maven从公共仓库下载插件而非私有仓库?
公司私有Nexus仓库仅存放少量私有库,主要镜像公共Maven仓库,但该仓库需VPN才能访问。当前通过settings.xml配置将所有Maven请求镜像到私有仓库,未连接VPN时构建Spring Boot项目,Maven无法下载spring-boot等插件,报错如下:
[ERROR] No plugin found for prefix 'spring-boot' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/bobbytables/.m2/repository), foo-nexus (https://foo/repository/foo-maven-group/)] -> [Help 1]
现有配置文件参考:
用户settings.xml
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <servers> <server> <id>FOOSNAPSHOTS</id> <username>foo-publisher</username> <password>12345</password> </server> <server> <id>BARRELEASES</id> <username>bar-publisher</username> <password>12345</password> </server> </servers> <mirrors> <mirror> <id>foo-nexus</id> <mirrorOf>*</mirrorOf> <url>https://foo/repository/foo-maven-group/</url> </mirror> <mirror> <id>bar-nexus</id> <mirrorOf>*</mirrorOf> <url>https://foo/repository/bar-maven-group/</url> </mirror> </mirrors> <profiles> <profile> <id>allow-snapshots</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>snapshots-repo</id> <url>https://foo/repository/hosted-foo-snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>foo-snapshots-repo</id> <url>https://foo/repository/hosted-bar-snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles> </settings>
父POM
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>foo.shared-maven-parent</groupId> <artifactId>shared-maven-parent-java</artifactId> <version>1.202211110800.52-x6937aa5.master</version> </parent> <groupId>foo.bar-service</groupId> <artifactId>bar-service</artifactId> <packaging>pom</packaging> <version>3.0-SNAPSHOT</version> <name>bar-service</name> <description>Foo Bar - Bar is Foo</description> <modules> <module>contract</module> <module>server</module> </modules> <properties> <mcu.version>${project.version}</mcu.version> <!-- Project's contract version --> <mcu.project.contract.version>1.202204111324.39-x6bb54a3.master</mcu.project.contract.version> </properties> </project>
服务POM
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>foo.bar-service</groupId> <artifactId>bar-service</artifactId> <version>3.0-SNAPSHOT</version> </parent> <groupId>foo.bar</groupId> <artifactId>server</artifactId> <packaging>jar</packaging> <name>Listing-command Server</name> <description>Listing-command Server</description> <properties> <java.version>17</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>foo.shared-maven-bom</groupId> <artifactId>shared-maven-bom-chassis</artifactId> <version>1.202211160925.72-xa9bdde9.master</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>foo.shared-commons.spring-boot</groupId> <artifactId>jetty-server</artifactId> <version>1.202211110857.90-xcb97a1c.master</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <!-- Starter for Stackdriver Trace --> </project>
核心问题是settings.xml中mirrorOf="*"将所有仓库请求路由到无法访问的私有Nexus,导致Maven无法从公共仓库获取插件。以下两种配置方式可解决问题:
方案一:用户级别配置(修改settings.xml)
通过多Profile实现仓库切换,默认使用公司私有仓库,无VPN时手动切换到公共仓库:
- 修改
settings.xml的profiles节点,拆分配置为两个Profile:
<profiles> <!-- 默认激活的公司私有仓库Profile --> <profile> <id>company-repos</id> <activation> <activeByDefault>true</activeByDefault> </activation> <mirrors> <mirror> <id>foo-nexus</id> <mirrorOf>*</mirrorOf> <url>https://foo/repository/foo-maven-group/</url> </mirror> </mirrors> <repositories> <repository> <id>snapshots-repo</id> <url>https://foo/repository/hosted-foo-snapshots</url> <releases><enabled>false</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository> <repository> <id>foo-snapshots-repo</id> <url>https://foo/repository/hosted-bar-snapshots</url> <releases><enabled>false</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository> </repositories> </profile> <!-- 公共仓库Profile,无VPN时激活 --> <profile> <id>public-repos</id> <!-- 配置插件仓库,解决spring-boot插件下载问题 --> <pluginRepositories> <pluginRepository> <id>central</id> <url>https://repo1.maven.org/maven2/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </pluginRepository> <pluginRepository> <id>spring-plugins</id> <url>https://repo.spring.io/plugins-release/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </pluginRepository> </pluginRepositories> <!-- 配置依赖仓库 --> <repositories> <repository> <id>central</id> <url>https://repo1.maven.org/maven2/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </repository> <repository> <id>spring-milestones</id> <url>https://repo.spring.io/milestone/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </repository> </repositories> </profile> </profiles>
- 无VPN时,执行构建命令切换到公共仓库Profile:
mvn clean install -Ppublic-repos,!company-repos
方案二:项目级别配置(修改pom.xml)
在项目POM中直接配置公共插件仓库,或显式声明Spring Boot插件坐标:
方式1:添加公共插件仓库
在服务POM(或父POM)中添加pluginRepositories节点:
<pluginRepositories> <pluginRepository> <id>central</id> <url>https://repo1.maven.org/maven2/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </pluginRepository> <pluginRepository> <id>spring-plugins</id> <url>https://repo.spring.io/plugins-release/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>false</enabled></snapshots> </pluginRepository> </pluginRepositories>
同时修改settings.xml中的镜像规则,排除这些公共仓库ID,避免请求被路由到私有Nexus:
<mirrors> <mirror> <id>foo-nexus</id> <!-- 排除公共仓库,仅镜像私有仓库请求 --> <mirrorOf>*,!central,!spring-plugins</mirrorOf> <url>https://foo/repository/foo-maven-group/</url> </mirror> </mirrors>
方式2:显式声明Spring Boot插件坐标
在服务POM的build/plugins节点中直接指定插件完整坐标,避免Maven通过前缀查找:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!-- 版本可从项目BOM继承,或手动指定对应版本 --> <version>${spring-boot.version}</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
内容的提问来源于stack exchange,提问作者tomaytotomato

