Maven构建仅更改文件

时间:2013-03-14 09:25:26

标签: java maven build continuous-integration

假设我有类似下面的模块结构

     Modules
       ->utils
       ->domain
       ->client
       ->services
       ->deploy (this is at the module level)

现在,我需要构建所有模块i.e utils, domain, client, services,,因为我正在加载所有上述模块的jar,以便客户端

所有罐子都在模块部署中组装完毕。

我的问题是,如果我更改了服务中的任何内容,那么有没有办法从deploy maven运行构建时可以识别它必须只构建services并因此构建它并将其部署在部署文件夹?

7 个答案:

答案 0 :(得分:24)

如果只调用“mvn install”而没有“clean”,编译器插件将只编译修改过的类。

答案 1 :(得分:11)

在多模块构建中,您可以使用:

mvn -pl ChangedModule compile
来自根模块的

将仅编译给定的 ChangedModule 。编译器插件只会编译已更改的文件。但是,您更改的模块可能会导致重新编译其他模块,这取决于 ChangedModule 。这可以通过使用以下方法来实现:

mvn -amd -pl ChangedModule compile

-amd表示也会依赖。这可以在不通过 mvn install 将整个模块安装到本地存储库中的情况下工作。

答案 2 :(得分:6)

如果您正在使用SVN和* nix,请从根模块

mvn install -amd -pl $(svn st | colrm 1 8 | sed 's /.*  ' | xargs echo | sed 's- -,:-g' | sed 's ^ : ') 

答案 3 :(得分:3)

对于GIT

mvn install -amd -pl $(git status | grep -E "modified:|deleted:|added:" | awk '{print $2}' | cut -f1 -d"/")

OR

在您的.bashrc文件中(.bashrc可以在主目录〜/ .bashrc中找到,或者如果不存在则创建它)添加以下功能。

mvn_changed_modules(){
    [ -z "$1" ] && echo "Expected command : mvn_changed_modules (install/build/clean or any maven command)" && exit 0

        modules=$(git status | grep -E "modified:|deleted:|added:" | awk '{print $2}' | cut -f1 -d"/")

                if [  -z "$modules" ];
                then
                        echo "No changes (modified / deleted / added)  found"
                else
                        echo "Changed modules are : `echo $modules`"
                        mvn install -amd -pl $modules
                fi
}


然后在重新启动bash (命令提示符)后,可以直接使用ROOT目录中的以下命令

  

smilyface @ machine> MainDir] $ mvn_changed_module install


工作原理?
根据问题mvn install -amd -pl services是在 services 模块"中进行某些更改时的命令。因此,首先从更改的文件中获取模块名称,并将其作为mvn-install命令的输入

比如说,下面是修改过的文件列表(git status的输出) -
服务 /pom.xml
服务 /ReadMe.txt
网络 /src/java/com/some/Name.java
然后servicesweb是需要构建/编译/安装的模块名称

答案 4 :(得分:2)

在尝试并使用上述建议后,我遇到了以下问题:

  1. Maven安装(不干净)仍然需要花费很多时间,对于几个项目来说可能需要10-20秒的额外时间。
  2. Sebasjm的解决方案快速且有用(我使用它几个月),但如果你有几个改变的项目,一直重建它们(如果你甚至没有改变任何东西)是一个巨大的浪费时间
  3. 对我来说真正有用的是将源修改日期与本地存储库中的.jar修改进行比较。如果你只检查VCS更改的文件(请参阅sebasjm的答案),那么日期比较将不会花费显着的时间(对我来说,100个更改的文件不到1秒)。 这种方法的主要好处是非常准确地重建真正改变的项目。 主要问题是做修改日期比较有点多于单行脚本。

    对于那些想要尝试它的人,但是懒得写这样的脚本自己分享我的版本:https://github.com/bugy/rebuilder(linux / windows)。 它可以做一些额外的有用的事情,但主要思想和中心算法如上所述。

答案 5 :(得分:2)

我有同样的挫败感,当时我还写了一个项目 - 唉它不可用,但我发现有人实现了类似的东西:

例如 - https://github.com/erickzanardo/maven-watcher

它使用nodejs并假设maven项目,但应该适用于Windows和unix。

我的实现的想法是观察更改,然后编译更改的内容。 - 有点像nodemon

所以例如

  • 当java文件发生变化时 - 我编译模块
  • 当一个类文件或jar更改时 - 我会做其他事情(例如在tomcat下复制jar并重启tomcat)

这两者是无关的..所以如果java编译失败,应该没有理由让jar文件更新..而且它非常稳定。

我在一个包含23K .java个文件的项目中使用过它,并且运行顺畅。

观看过程需要几秒钟才能启动 - 但是只有在检测到更改后它才会运行,因此总体体验非常好。

我打算添加的下一步类似于您的SVN支持 - 列出修改后的文件并将其用作初始化。

需要注意的重要事项 - 如果编译失败,它将在下次修改时重试。因此,如果您正在修改多个jar,并且编译失败,只要您编写代码,它将重试编译每个代码更改的所有内容,直到它成功编译。

如果您希望我可以尝试找到我的旧项目,请稍微修改一下并发布它。

答案 6 :(得分:0)

到目前为止,发布的问题和答案并未考虑依赖关系树。如果更改了 utils 模块怎么办?我们需要重建(至少重新测试)它以及所有依赖于它的模块。

这样做的方式: