使用maven-build-cache-extension实现Maven增量快速构建Java项目


随着 Maven 3.9.0的发布,现在可以利用maven-build-cache-extensionMaven 项目中的增量构建来获益。

此功能可以缩短构建时间(在您的本地工作流程和 CI 中)。它缓存模块构建,避免不必要和/或昂贵的任务:

  • 可以通过.mvn/extensions.xml
  • 或通过修改您的pom.xml增加:

<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">

    <extension>
        <groupId>org.apache.maven.extensions</groupId>
        <artifactId>maven-build-cache-extension</artifactId>
        <version>1.0.0</version>
    </extension>

</extensions>

这个解决方案提供了更多的灵活性,因为你可以通过存储在.mvn文件夹下的maven-build-cache-config.xml文件来配置扩展。如果没有找到配置文件,将使用合理的默认值。

如果您使用pom.xml方法,您可以将该插件添加到您的项目->build->extensions。


<project>
    ...
    <build>
        <extensions>
            <extension>
                <groupId>org.apache.maven.extensions</groupId>
                <artifactId>maven-build-cache-extension</artifactId>
                <version>1.0.0</version>
            </extension>
        </extensions>
    </build>
    ...
</project>

击中缓存Cache hit

# Running a maven goal
mvn clean test
[...]
# Enabling cache and hash algorithm
[INFO] Cache configuration is not available at configured path C:\<REDACTED>\.mvn\maven-build-cache-config.xml, cache is enabled with defaults
[INFO] Using XX hash algorithm for cache
[...]
# For each module ...
[INFO] Going to calculate checksum for project [groupId=com.example, artifactId=demo]
[INFO] Scanning plugins configurations to find input files. Probing is enabled, values will be checked for presence in file system
[INFO] Found 3 input files. Project dir processing: 13, plugins: 6 millis
[INFO] Project inputs calculated in 39 ms. XX checksum [596f60b3f5056d7d] calculated in 16 ms.
[INFO] Attempting to restore project com.example:demo from build cache
[INFO] Remote cache is incomplete or missing, trying local build for com.example:demo
[INFO] Local build found by checksum 596f60b3f5056d7d
[INFO] Found cached build, restoring com.example:demo from cache by checksum 596f60b3f5056d7d
[INFO] Skipping plugin execution (cached): resources:resources
[INFO] Skipping plugin execution (cached): compiler:compile
[INFO] Skipping plugin execution (cached): resources:testResources
[INFO] Skipping plugin execution (cached): compiler:testCompile
[INFO] Skipping plugin execution (cached): surefire:test

我们可以看到,maven完全跳过了编译和测试执行,重新使用了缓存的数据。这表示hit cache
这也是通过每个模块的缓存来实现的,也就是说,在一个多模块的maven项目中,只有受影响的模块会被构建。


缓存Miss
当使用该扩展运行任意1个maven目标时,您应该在maven控制台看到打印的新信息

# Running a maven goal
mvn clean test
[...]
# Enabling cache and hash algorithm
[INFO] Cache configuration is not available at configured path C:\<REDACTED>\.mvn\maven-build-cache-config.xml, cache is enabled with defaults
[INFO] Using XX hash algorithm for cache
[...]
# For each module ...
[INFO] Going to calculate checksum for project [groupId=com.example, artifactId=demo]
[INFO] Scanning plugins configurations to find input files. Probing is enabled, values will be checked for presence in file system
[INFO] Found 3 input files. Project dir processing: 16, plugins: 8 millis
[INFO] Project inputs calculated in 58 ms. XX checksum [596f60b3f5056d7d] calculated in 25 ms.
[INFO] Attempting to restore project com.example:demo from build cache
[INFO] Remote cache is incomplete or missing, trying local build for com.example:demo
[INFO] Local build was not found by checksum 596f60b3f5056d7d for com.example:demo

我们可以看到:

  • 用XX散列算法检测默认配置
  • 根据输入文件和插件配置计算模块构建执行校验和
  • 搜索相应的构建缓存
  • 如果在缓存没有找到,则继续构建(缓存Miss)。
  • 构建缓存信息存储在你的 ~/.m2 仓库中,在一个构建缓存文件夹下。这对调试任何缓存错误很有用。

每个模块都有一个文件buildinfo.xml(ref),包含缓存数据(项目输入、maven执行)和生成的工件。

性能改进
我做了一些小测试,在两个项目上运行mvn clean verify -DskipTests:

一个通过https://start.spring.io/ 创建的最小的spring-boot应用
构建我当前的项目:一个多模块的项目,包括15个模块,从spring boot应用程序到普通libs,生成的代码源等。

我看到在我的构建上有4-10个性能改进,甚至在考虑到测试时更加明显,无论如何我们应该一直这样做。我一下子就被说服了

备择方案
在测试这个插件之前,我主要使用了两种技术来加速我的 Maven 构建(Nicolas Fränkel对此有一篇很好的文章)。

  • 第一个是maven 守护进程:该项目旨在通过简化并行构建来加快 maven 构建。它不提供此扩展提供的增量构建。
    好消息是,除了此扩展之外,它还可以用于更快的构建盛会(检查相关的 github 问题-针对发布0.10.x)。
  • 第二个是使用 maven 反应器选项来构建特定的模块。例如。 运行mvn -pl :module1 --also-make将构建特定module1的同时还构建所需的项目2(忽略其余部分)。
    虽然这是我每天在本地和 CI 构建中使用的巧妙技巧,但它仍然没有受益于扩展提供的缓存性能改进。

我很喜欢这个扩展,我仍然可以从这些工具中受益,并且仍然可以从大规模的构建改进中获益。

故障排除
如果你偶然发现了一个奇怪的行为(检查未解决的问题),我发现目前处理错误的两种最佳方法是:

  • 手动删除缓存文件夹,位于~/.m2/build-cache
  • 通过命令行禁用扩展-Dmaven.build.cache.enabled=false

结论
在您的 Maven 项目中利用maven-build-cache-extension可以避免不必要或昂贵的任务,从而显着缩短构建时间。希望通过遵循本文中列出的步骤,您可以轻松开始并从本地工作流和 CI 中更快的构建时间中获益。