如何用Ansible动态修改pom.xml配置本地JAR依赖?
问题
需要动态修改pom.xml文件,让Maven针对特定groupId使用本地安装的JAR包,具体需求:
- 将所有匹配依赖的scope修改/设置为
system。 - 为每个匹配依赖添加
systemPath,其路径文件名由artifactId生成(例如myGroup-agent-api对应agent-api.jar,路径为${application_path}/jar/agent-api.jar)。
示例原依赖配置:
<dependency> <groupId>myGroup</groupId> <artifactId>myGroup-agent-api</artifactId> <version>3.1.38.13</version> <scope>provided</scope> </dependency>
修改后目标配置:
<dependency> <groupId>myGroup</groupId> <artifactId>myGroup-agent-api</artifactId> <version>3.1.38.13</version> <scope>system</scope> <systemPath>${application_path}/jar/agent-api.jar</systemPath> </dependency>
已完成第一部分,使用Ansible的xml模块修改scope的任务:
- name: Set scope to system for myGroup if {{ module.name }} uses any xml: path: '{{ app_path }}/{{ module.name }}/pom.xml' namespaces: x: http://maven.apache.org/POM/4.0.0 xpath: '//x:dependency/x:groupId[text()="myGroup"]/../x:scope' value: system register: xmlfound when: java_files.matched failed_when: - xmlfound is failed - >- 'in order to spawn nodes' not in xmlfound.msg
(注:设置failed_when是因为当lxml找不到匹配依赖时会报错,需要忽略这种情况)
现在需要实现第二部分:根据每个匹配依赖的artifactId生成对应的systemPath并添加到依赖节点中。
更新补充:
- 确定使用Ansible,因为修改是机械性操作,添加新配置文件会增加开发者维护负担——开发者本地构建时需从仓库下载JAR包,而服务器构建时由Ansible拉取代码、修改pom.xml后调用Maven构建。
- 考虑过使用
add_children,但每个依赖的systemPath不同,需由artifactId生成,不清楚参数如何设置。 - 需保留
failed_when设置,避免无匹配依赖的POM触发错误。
解决方案
要实现根据artifactId动态生成systemPath并添加到对应依赖节点,需分两步处理:先提取匹配的依赖节点信息,再循环处理每个节点添加/更新systemPath。
步骤1:提取匹配的依赖节点数据
先用xml模块获取所有groupId为myGroup的依赖节点的artifactId,为后续循环处理做准备:
- name: Fetch all myGroup dependencies and their artifactIds xml: path: '{{ app_path }}/{{ module.name }}/pom.xml' namespaces: x: http://maven.apache.org/POM/4.0.0 xpath: '//x:dependency[x:groupId[text()="myGroup"]]' content: text register: mygroup_deps when: java_files.matched failed_when: - mygroup_deps is failed - >- 'in order to spawn nodes' not in mygroup_deps.msg
步骤2:循环处理每个依赖节点,添加/更新systemPath
利用json_query提取每个依赖的artifactId,通过正则替换去掉前缀myGroup-生成目标JAR文件名,再用xml模块的state: present自动处理节点的创建或更新:
- name: Add/Update systemPath for each myGroup dependency xml: path: '{{ app_path }}/{{ module.name }}/pom.xml' namespaces: x: http://maven.apache.org/POM/4.0.0 xpath: '//x:dependency[x:groupId[text()="myGroup"] and x:artifactId[text()="{{ item.artifactId }}"]]/x:systemPath' value: '${application_path}/jar/{{ item.artifactId | regex_replace("^myGroup-", "") }}.jar' state: present loop: "{{ mygroup_deps.matches | json_query('[].{artifactId: x.dependency.x.artifactId[0]}') }}" when: - java_files.matched - mygroup_deps.matches | length > 0 register: xml_result failed_when: - xml_result is failed - >- 'in order to spawn nodes' not in xml_result.msg
关键说明:
regex_replace("^myGroup-", ""):移除artifactId前缀,生成目标JAR文件名(如myGroup-agent-api转为agent-api)。state: present:自动判断节点状态,存在则更新值,不存在则创建节点并赋值。- 循环遍历所有匹配依赖,确保每个符合条件的依赖都被处理。
整合后的完整任务序列
将修改scope和添加systemPath的任务按顺序组合:
- name: Set scope to system for myGroup dependencies xml: path: '{{ app_path }}/{{ module.name }}/pom.xml' namespaces: x: http://maven.apache.org/POM/4.0.0 xpath: '//x:dependency/x:groupId[text()="myGroup"]/../x:scope' value: system register: xmlfound when: java_files.matched failed_when: - xmlfound is failed - >- 'in order to spawn nodes' not in xmlfound.msg - name: Fetch all myGroup dependencies and their artifactIds xml: path: '{{ app_path }}/{{ module.name }}/pom.xml' namespaces: x: http://maven.apache.org/POM/4.0.0 xpath: '//x:dependency[x:groupId[text()="myGroup"]]' content: text register: mygroup_deps when: java_files.matched failed_when: - mygroup_deps is failed - >- 'in order to spawn nodes' not in mygroup_deps.msg - name: Add/Update systemPath for each myGroup dependency xml: path: '{{ app_path }}/{{ module.name }}/pom.xml' namespaces: x: http://maven.apache.org/POM/4.0.0 xpath: '//x:dependency[x:groupId[text()="myGroup"] and x:artifactId[text()="{{ item.artifactId }}"]]/x:systemPath' value: '${application_path}/jar/{{ item.artifactId | regex_replace("^myGroup-", "") }}.jar' state: present loop: "{{ mygroup_deps.matches | json_query('[].{artifactId: x.dependency.x.artifactId[0]}') }}" when: - java_files.matched - mygroup_deps.matches | length > 0 register: xml_result failed_when: - xml_result is failed - >- 'in order to spawn nodes' not in xml_result.msg
内容的提问来源于stack exchange,提问作者Mikhail T.
相关产品推荐
相关产品推荐

