Skip to main content

Maven

Tips#

  • Maven 包类型
    • pom - Project Object Model
    • jar - Java Application Archive
    • ear - Enterprise Application Archive
    • war - Web Application Archive
    • rar - Resource Adapter Archive
属性说明
maven.javadoc.skip不调用 Javadoc 插件
maven.test.skip不编译测试,不执行测试
maven.test.skip.exec不执行测试,但编译测试包
maven.repo.remote远程仓库
maven.repo.local本地仓库
socksProxyHost
socksProxyPort
Socks 代理
httpProxyHost
httpProxyPort
Http 代理
httpsProxyHost
httpsProxyPort
Https 代理
-pl, --projects        Build specified reactor projects instead of all projects-am, --also-make        If project list is specified, also build projects required by the list
# 修改远程仓库和本地仓库mvn package \  -Dmaven.repo.remote=http://maven.aliyun.com/nexus/content/groups/public \  -Dmaven.repo.local="$HOME/repo"
# 下载包mvn dependency:get \  -DrepoUrl=http://maven.aliyun.com/nexus/content/groups/public \  -Dartifact=org.redisson:redisson:3.2.0
# 获取项目信息,在命令行下比较有用mvn -q -Dexec.executable="echo" -Dexec.args='${project.artifactId}' --non-recursive org.codehaus.mojo:exec-maven-plugin:exec
# 强制更新 SNAPSHOTmvn clean install -U

总量 https://search.maven.org/stats

官方 mirror http://repo.maven.apache.org/maven2/.meta/repository-metadata.xml

pom.xml#

settings.xml#

  • 默认配置文件位于 $HOME/.m2/settings.xml
    • 如果没有,可以从 Maven 安装目录拷贝

代理设置#

<proxy>    <id>myproxy</id>    <active>true</active>    <protocol>http</protocol>    <host>127.0.0.1</host>    <port>8087</port>    <nonProxyHosts>localhost|127.0.0.1</nonProxyHosts></proxy>

镜像#

一般使用镜像有以下几种方式

  • 在 POM 中添加仓库
    • 粘贴复制下就能使用
    • 会持久在项目中
      • 团队中其他人也不需要配置
    • 如果在镜像的仓库中找不到会在中央仓库找
  • 在 setting 中添加镜像
    • 需要调整 setting.xml 相对麻烦一些
    • 在仓库中找不到会出错
    • 当项目中有多个模块时,使用镜像可能会出现找不到本地模块的问题
  • 在 setting 中添加 profile

阿里云#

可以在 POM 中加入如下仓库配置来使用 阿里云的 Maven 仓库镜像。

⚠️ 注意 阿里云 Maven 仓库镜像同步相对较慢,可能几天或者十几天才能同步

https://repo.maven.apache.org/maven2/ https://repo1.maven.apache.org/maven2/

<repositories>    <repository>        <id>aliyun</id>        <url>http://maven.aliyun.com/nexus/content/groups/public</url>    </repository></repositories><pluginRepositories>    <pluginRepository>        <id>aliyun</id>        <url>http://maven.aliyun.com/nexus/content/groups/public</url>    </pluginRepository></pluginRepositories>

谷歌#

同步速度快,访问速度也很快,没有被封

<repositories>    <repository>       <id>google</id>       <url>https://maven-central.storage.googleapis.com</url>    </repository></repositories><pluginRepositories>    <pluginRepository>        <id>google</id>        <url>https://maven-central.storage.googleapis.com</url>    </pluginRepository></pluginRepositories>

Settings#

也可以在 settings.xml 里配置

Android https://maven.google.com/web/index.html

<settings>  <mirrors>    <!-- Google -->    <mirror>      <id>google-maven-central</id>      <name>Google Maven Central</name>      <url>https://maven-central.storage.googleapis.com</url>      <mirrorOf>central</mirrorOf>    </mirror>    <!-- 阿里 -->    <mirror>         <id>aliyun</id>         <mirrorOf>central</mirrorOf>         <name>aliyun</name>         <url>http://maven.aliyun.com/nexus/content/groups/public</url>    </mirror>  </mirrors></settings>

插件#

  • 插件如果不制定 groupId 则默认为 org.apache.maven.plugins
  • 官方插件列表
  • 默认生命周期包含的插件 Plugin Bindings for default Lifecycle Reference
    • pom 包
      • install - maven-install-plugin:install
      • deploy - maven-deploy-plugin:deploy
    • jar 包
      • process-resources - maven-resources-plugin:resources
      • compile - maven-compiler-plugin:compile
      • process-test-resources - maven-resources-plugin:testResources
      • test-compile - maven-compiler-plugin:testCompile
      • test - maven-surefire-plugin:test
      • package - maven-jar-plugin:jar
      • install - maven-install-plugin:install
      • deploy - maven-deploy-plugin:deploy

mvn dependency:resolve -Dclassifier=javadoc mvn dependency:resolve -Dclassifier=sources

<profile>    <id>downloadSources</id>    <properties>        <downloadSources>true</downloadSources>        <downloadJavadocs>true</downloadJavadocs>    </properties></profile>
downloadSources

mvn -N io.takari:maven:0.7.7:wrapper -Dmaven=3.6.3

maven-install-plugin#

安装 Jar 包到本地仓库#

mvn install:install-file \  -Dfile=mylib-$VERSION.jar \  -DgroupId=me.wener.lib \  -DartifactId=mylib \  -Dversion=$VERSION \  -Dpackaging=jar \  -DgeneratePom=true

maven-jar-plugin#

maven-shade-plugin#

<!-- 常用配置,按需粘贴 --><configuration>    <!-- 不创建 reduced pom 文件 -->    <createDependencyReducedPom>false</createDependencyReducedPom>    <!-- 附加 shaded 的文件,默认会上传 shaded 的问题 -->    <shadedArtifactAttached>true</shadedArtifactAttached>    <!-- shaded 的 classfier,依赖时指定 classfier 即可 -->    <shadedClassifierName>jar-with-dependencies</shadedClassifierName>    <!-- 排除签名相关,否则 shade 后签名异常,切排除 java9 后的 module 信息 -->    <filters>        <filter>            <artifact>*:*</artifact>            <excludes>                <exclude>META-INF/*.SF</exclude>                <exclude>META-INF/*.DSA</exclude>                <exclude>META-INF/*.RSA</exclude>                <exclude>module-info.class</exclude>            </excludes>        </filter>    </filters>    <artifactSet>        <excludes>            <!-- 排除包,不做 shade -->            <exclude>org.slf4j:*</exclude>        </excludes>    </artifactSet>    <!-- 转换,按需配置 -->    <transformers>        <!-- 合并文件为一个,附加的方式 -->        <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">            <resource>config.properties</resource>        </transformer>        <!-- 处理 ServiceLoader 的定义 -->        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>        <!-- 合并 META-INF/NOTICE.TXT 文件 -->        <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"/>    </transformers>    <!-- 避免版本冲突,做 shade -->    <relocations>        <relocation>            <pattern>com.google.common</pattern>            <shadedPattern>me.wener.shade.guava</shadedPattern>        </relocation>    </relocations></configuration>

shade one & relocation#

将 guava 重定位到 me.wener.guava

<plugin>    <artifactId>maven-shade-plugin</artifactId>    <executions>        <execution>            <phase>package</phase>            <goals>                <goal>shade</goal>            </goals>            <configuration>                <artifactSet>                    <includes>                        <include>com.google.guava:guava</include>                    </includes>                </artifactSet>                <relocations>                    <relocation>                        <pattern>com.google.common</pattern>                        <shadedPattern>me.wener.guava</shadedPattern>                    </relocation>                </relocations>            </configuration>        </execution>    </executions></plugin>

shade all & relocation & new jar#

会生成另外一个 jar jraphql-${project.version}-shaded

<plugin>  <artifactId>maven-shade-plugin</artifactId>  <executions>    <execution>      <phase>package</phase>      <goals>        <goal>shade</goal>      </goals>      <configuration>        <finalName>jraphql-${project.version}-shaded</finalName>        <relocations>          <relocation>            <pattern>com.google.common</pattern>            <shadedPattern>shaded.com.google.common</shadedPattern>          </relocation>        </relocations>        <artifactSet>          <includes>            <include>*:*</include>          </includes>        </artifactSet>      </configuration>    </execution>  </executions></plugin>

maven-release-plugin#

  • Maven Release Plugin
  • 执行目标
    • release:clean 在准备发布后清理
    • release:prepare 在 SCM 中生成准备提交
    • release:prepare-with-pom 在 SCM 中生成准备提交并生成 POM
    • release:rollback 回退之前的发布
    • release:perform 从 SCM 执行发布
    • release:stage 在制定的目录从 SCM 发布
    • release:branch 创建分支并更新版本
    • release:update-versions 更新 POM 中的版本
  • 基本的逻辑是先提交到 SCM,在从 SCM 拉取到一个临时目录进行构建发布
# 查看帮助mvn release:help# 准备发布mvn release:clean release:prepare# 执行发布# deploy & pushmvn release:perform# 回滚操作mvn release:rollback

maven-gpg-plugin#

GPG 的基本操作

# 生成 keygpg --gen-key# 查看 keygpg --list-keys# 上传gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 09CB6FEF# 生成签名gpg -ab artifact.jar# 验证签名gpg --verify artifact.jar.asc

在验证时进行签名操作

<plugin>    <groupId>org.apache.maven.plugins</groupId>    <artifactId>maven-gpg-plugin</artifactId>    <version>1.4</version>    <executions>        <execution>            <id>sign-artifacts</id>            <phase>verify</phase>            <goals>                <goal>sign</goal>            </goals>        </execution>    </executions></plugin>

spring-boot-maven-plugin#

生成 build-info#

默认位置为 META-INF/build-info.properties

<executions>  <execution>    <goals>      <goal>build-info</goal>    </goals>    <configuration>      <additionalProperties>        <encoding.source>UTF-8</encoding.source>        <encoding.reporting>UTF-8</encoding.reporting>        <java.source>${maven.compiler.source}</java.source>        <java.target>${maven.compiler.target}</java.target>      </additionalProperties>    </configuration>  </execution></executions>

git-commit-id-plugin#

Maven plugin which includes build-time git repository information into an POJO / *.properties

只生成部分属性#

<plugin>    <groupId>pl.project13.maven</groupId>    <artifactId>git-commit-id-plugin</artifactId>    <executions>        <execution>            <goals>                <goal>revision</goal>            </goals>        </execution>    </executions>    <configuration>        <verbose>false</verbose>        <dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>        <generateGitPropertiesFile>true</generateGitPropertiesFile>        <generateGitPropertiesFilename>            ${project.build.outputDirectory}/git.properties        </generateGitPropertiesFilename>        <includeOnlyProperties>            <includeOnlyProperty>^git.branch$</includeOnlyProperty>            <includeOnlyProperty>^git.build.time$</includeOnlyProperty>            <includeOnlyProperty>^git.build.version$</includeOnlyProperty>            <includeOnlyProperty>^git.commit.id.abbrev$</includeOnlyProperty>            <includeOnlyProperty>^git.commit.time$</includeOnlyProperty>        </includeOnlyProperties>    </configuration></plugin>

仓库管理#

# ARCHIVA_BASE 可修改存储位置, 默认为 /var/archiva# ARCHIVA_CONTEXT_PATH 可在反向代理是使用, 默认为 /docker run -v $PWD/archiva:/var/archiva -p 8080:8080 -d ninjaben/archiva-docker

中央仓库#

Sonatype Central#

  • OSSRH Guide
  • Deploying to OSSRH with Apache Maven
  • Requirements
  • 发布到 Sonatype 后,大约 10m 后会同步到中央仓库
  • 坐标申请
    • https://issues.sonatype.org/ 创建账号
    • 创建一个 issues 描述希望使用的 groupId 并简单阐述放的内容
    • 等待审批完成
  • 要求
    • 提供 Javadoc 和 Sources
    • 使用 GPG/PGP 签名,生成 .asc 文件
    • pom 要求
      • 正确的坐标
      • 版本不能为 -SNAPSHOT
      • 名字,描述,网址 - name,description,url
      • name 可接受 ${project.groupId}:${project.artifactId}
      • 许可信息 - licenses
      • 开发者信息 - developers
      • SCM 信息 - scm

Maven 部署#

手动部署#

# https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
# 编译打包mvn jar:jar source:jar javadoc:jarcd targetcp ../pom.xml .# 签名NAME=MyLib-0.0.1rm *.ascgpg -ab pom.xmlgpg -ab $NAME.jargpg -ab $NAME-sources.jargpg -ab $NAME-javadoc.jar
# http://maven.apache.org/plugins/maven-gpg-plugin/sign-mojo.html# 可以直接在命令行上指定密码PASSPHRASE=xxxmvn gpg:sign-and-deploy-file -Dgpg.passphrase=$PASSPHRASE \    -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \  -DrepositoryId=sonatype-nexus-staging -DpomFile=pom.xml \  -Dfile=NAME.jar
mvn gpg:sign-and-deploy-file -Dgpg.passphrase=$PASSPHRASE \    -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \  -DrepositoryId=sonatype-nexus-staging -DpomFile=pom.xml \  -Dfile=$NAME-sources.jar -Dclassifier=sources
mvn gpg:sign-and-deploy-file -Dgpg.passphrase=$PASSPHRASE \    -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \  -DrepositoryId=sonatype-nexus-staging -DpomFile=pom.xml \  -Dfile=$NAME-javadoc.jar -Dclassifier=javadoc

FAQ#

optional vs provided#

  • optional 只影响包的传递性, 不影响包的 ClassPath
  • provided 只在 compile 和 test 下存在, 并且不会传递
  • 所以区别在于 optional 在 runtime 时生效, 而 provided 不生效

Scope 的作用域#

scopecompiletestruntimetransitive
compileYYYY
test-Y--
providedYY--
runtime-YYY
systemYY-Y

Current maven session contains banned repository urls, please double check your pom or settings.xml#