1 Maven项目结构
a-maven-project
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ ├── java
│ └── resources
└── target
1.1 子模块管理
在软件开发中,把一个大项目分拆为多个模块是降低软件复杂度的有效方法:
┌ ─ ─ ─ ─ ─ ─ ┐
┌─────────┐
│ │Module A │ │
└─────────┘
┌──────────────┐ split │ ┌─────────┐ │
│Single Project│───────> │Module B │
└──────────────┘ │ └─────────┘ │
┌─────────┐
│ │Module C │ │
└─────────┘
└ ─ ─ ─ ─ ─ ─ ┘
对于Maven工程来说,原来是一个大项目:
single-project
├── pom.xml
└── src
现在可以分拆成3个模块:
mutiple-project
├── module-a
│ ├── pom.xml
│ └── src
├── module-b
│ ├── pom.xml
│ └── src
└── module-c
├── pom.xml
└── src
Maven可以有效地管理多个模块,我们只需要把每个模块当作一个独立的Maven项目,它们有各自独立的pom.xml。例如,模块A的pom.xml:
这样,在根目录执行mvn clean package时,Maven根据根目录的pom.xml找到包括parent在内的共4个<module>,一次性全部编译。
2 Maven 配置文件
2.1 构建配置文件类型
| 类型 | 在哪定义 |
|---|---|
| 项目级(Per Project) | 定义在项目的POM文件pom.xml中 |
| 用户级 (Per User) | 定义在Maven的设置xml文件中 (%USER_HOME%/.m2/settings.xml) |
| 全局(Global) | 定义在 Maven 全局的设置 xml 文件中 (%M2_HOME%/conf/settings.xml) |
# 1
vim ~/.bash_profile
# 2
#export M2_HOME=/Users/xxx/apache-maven-3.3.9
export M2_HOME=/Users/xxx/opt/apache-maven-3.8.4
export PATH=$PATH:$M2_HOME/bin
# 3
source ~/.bash_profile
查看当前生效pom, 经过父子pom叠加、覆盖、复写后的最终效果:
mvn help:effective-pom -s /Users/xxx/settings.xml
2.2 配置文件scope
[DEBUG] Reading global settings from /Users/xxx/opt/apache-maven-3.8.4/conf/settings.xml
[DEBUG] Reading user settings from /Users/xxx/.m2/settings.xml
[DEBUG] Reading global toolchains from /Users/xxx/opt/apache-maven-3.8.4/conf/toolchains.xml
[DEBUG] Reading user toolchains from /Users/xxx/.m2/toolchains.xml
[DEBUG] Using local repository at /Users/xxx/.m2/repository
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10.0 for /Users/xxx/.m2/repository
注:
Maven3却要配置一个名为M2_HOME的环境变量,这主要是因为在Maven1时环境变量配置为MAVEN_HOME,
在Maven2时改为了M2_HOME,而在Maven3则继续沿用了这个命名,
不过在Maven3.5.0以后,官方也舍弃了M2_HOME,因此我们现在其实只需要在Path中配置/apache-maven-3.6.3/bin即可,本文依旧沿用了M2_HOME**
3 约定配置
Maven 提倡使用一个共同的标准目录结构,Maven 使用约定优于配置的原则,大家尽可能的遵守这样的目录结构。如下所示:
| 目录 | 目的 |
|---|---|
| ${basedir} | 存放pom.xml和所有的子目录 |
| ${basedir}/src/main/java | 项目的java源代码 |
| ${basedir}/src/main/resources | 项目的资源,比如说property文件,springmvc.xml |
| ${basedir}/src/test/java | 项目的测试类,比如说Junit代码 |
| ${basedir}/src/test/resources | 测试用的资源 |
| ${basedir}/src/main/webapp/WEB-INF | web应用文件目录,web项目的信息,比如存放web.xml、本地图片、jsp视图页面 |
| ${basedir}/target | 打包输出目录 |
| ${basedir}/target/classes | 编译输出目录 |
| ${basedir}/target/test-classes | 测试编译输出目录 |
| Test.java | Maven只会自动运行符合该命名规则的测试类 |
| ~/.m2/repository | Maven默认的本地仓库目录位置 |
| ${version} | 项目版本 |
| ${project.baseUri} | 项目文件地址 |
| ${project.build.directory} | 源码路径 |
4 自定义全局变量
我们可以在 properties 定义全局变量,然后使用 ${变量名} 统一配置依赖的坐标。例如:
<properties>
<mysql.version>8.0.27</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
5 依赖管理
5.1 依赖范围
`compile`、`test`、`runtime`和`provided`
Scope 说明 示例
compile 编译时需要用到该jar包(默认) commons-logging
test 编译Test时需要用到该jar包 junit
runtime 编译时不需要,但运行时需要用到 mysql
provided 编译时需要用到,但运行时由JDK或某个服务器提供 servlet-api
5.2依赖调节原则
第一声明者优先原则
5.3 依赖调节原则
路径近者优先原则 --直接依赖大于依赖传递
5.4 排除依赖
exclusions标签
idea里可以使用mavenHelper自动排查
5.5 版本锁定
dependencyManagement标签限定版本号;
dependencyManagement 标签并不能真正引用依赖,它只是规定了依赖的版本,便于我们统一管理。
6 Maven坐标
对于某个依赖,Maven只需要3个变量即可唯一确定某个jar包:
groupId:属于组织的名称,类似Java的包名;
artifactId:该jar包自身的名称,类似Java的类名;
version:该jar包的版本。
通过上述3个变量,即可唯一确定某个jar包。
Maven通过对jar包进行PGP签名确保任何一个jar包一经发布就无法修改。
修改已发布jar包的唯一方法是发布一个新版本。
因此,某个jar包一旦被Maven下载过,即可永久地安全缓存在本地。
注:只有以-SNAPSHOT结尾的版本号会被Maven视为开发版本,开发版本每次都会重复下载;
这种SNAPSHOT版本只能用于内部私有的Maven repo,公开发布的版本不允许出现SNAPSHOT。
7 Maven镜像
除了可以从Maven的中央仓库下载外,还可以从Maven的镜像仓库下载。
如果访问Maven的中央仓库非常慢,我们可以选择一个速度较快的Maven的镜像仓库。
Maven镜像仓库定期从中央仓库同步:
slow ┌───────────────────┐
┌─────────────>│Maven Central Repo.│
│ └───────────────────┘
│ │
│ │sync
│ ▼
┌───────┐ fast ┌───────────────────┐
│ User │─────────>│Maven Mirror Repo. │
└───────┘ └───────────────────┘
中国区用户可以使用阿里云提供的Maven镜像仓库。
使用Maven镜像仓库需要一个配置,在用户主目录下进入.m2目录,创建一个settings.xml配置文件,内容如下:
<settings>
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<mirrorOf>central</mirrorOf>
<!-- 国内推荐阿里云的Maven镜像 -->
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
</mirrors>
</settings>
配置镜像仓库后,Maven的下载速度就会非常快。
8 Maven 中央仓库
最后一个问题:如果我们要引用一个第三方组件,比如okhttp,如何确切地获得它的groupId、artifactId和version方法是通过search.maven.org搜索关键字,找到对应的组件后,直接复制:
9 Maven Lifecycle & Phase
有一些与 Maven 生命周期相关的重要概念需要说明:
当一个阶段通过 Maven 命令调用时,例如 mvn compile,只有该阶段之前以及包括该阶段在内的所有阶段会被执行。
不同的 maven 目标将根据打包的类型(JAR / WAR / EAR),被绑定到不同的 Maven 生命周期阶段。
Maven的生命周期由一系列阶段(phase)构成,以内置的生命周期default为例,它包含以下phase:
- validate
- initialize
- generate-sources
- process-sources
- generate-resources
- process-resources
- compile
- process-classes
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources
- test-compile
- process-test-classes
- test
- prepare-package
- package
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install
- deploy
如果我们运行mvn package,Maven就会执行default生命周期,它会从开始一直运行到package这个phase为止:
- validate
- ...
- package
如果我们运行mvn compile,Maven也会执行default生命周期,但这次它只会运行到compile,即以下几个phase:
- validate
- ...
- compile
Maven另一个常用的生命周期是clean,它会执行3个phase:
- pre-clean
- clean (注意这个clean不是lifecycle而是phase)
- post-clean
所以,我们使用mvn这个命令时,后面的参数是phase,Maven自动根据生命周期运行到指定的phase。
更复杂的例子是指定多个phase,例如,运行mvn clean package,Maven先执行clean生命周期并运行到clean这个phase,然后执行default生命周期并运行到package这个phase,实际执行的phase如下:
- pre-clean
- clean (注意这个clean是phase)
- validate
- ...
- package
在实际开发过程中,经常使用的命令有:
mvn clean:清理所有生成的class和jar;
mvn clean compile:先清理,再执行到compile;
mvn clean test:先清理,再执行到test,因为执行test前必须执行compile,所以这里不必指定compile;
mvn clean package:先清理,再执行到package。
大多数phase在执行过程中,因为我们通常没有在pom.xml中配置相关的设置,所以这些phase什么事情都不做。
经常用到的phase其实只有几个:
- clean:清理
- compile:编译
- test:运行测试
- package:打包
10 Maven Goal
执行一个phase又会触发一个或多个goal:
| 执行的Phase | 对应执行的Goal |
|---|---|
| compile | compiler:compile |
| test | compiler:testCompile surefire:test |
goal的命名总是abc:xyz这种形式。
看到这里,相信大家对lifecycle、phase和goal已经明白了吧?
其实我们类比一下就明白了:
- lifecycle相当于Java的package,它包含一个或多个phase;
- phase相当于Java的class,它包含一个或多个goal;
- goal相当于class的method,它其实才是真正干活的。
大多数情况,我们只要指定phase,就默认执行这些phase默认绑定的goal,只有少数情况,我们可以直接指定运行一个goal,例如,启动Tomcat服务器:
mvn tomcat:run
11 Maven Plugin
Maven的lifecycle,phase和goal:使用Maven构建项目就是执行lifecycle,执行到指定的phase为止。
每个phase会执行自己默认的一个或多个goal。
goal是最小任务单元。
我们以compile这个phase为例,如果执行:
mvn compile
Maven将执行compile这个phase,这个phase会调用compiler插件执行关联的compiler:compile这个goal。
实际上,执行每个phase,都是通过某个插件(plugin)来执行的,Maven本身其实并不知道如何执行compile,它只是负责找到对应的compiler插件,然后执行默认的compiler:compile这个goal来完成编译。
所以,使用Maven,实际上就是配置好需要使用的插件,然后通过phase调用它们。
Maven已经内置了一些常用的标准插件:
| 插件名称 | 对应执行的phase |
|---|---|
| clean | clean |
| compiler | compile |
| surefire | test |
| jar | package |
如果标准插件无法满足需求,我们还可以使用自定义插件。使用自定义插件的时候,需要声明。例如,使用maven-shade-plugin可以创建一个可执行的jar,要使用这个插件,需要在pom.xml中声明它:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
自定义插件往往需要一些配置,例如,maven-shade-plugin需要指定Java程序的入口,它的配置是:
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.itranswarp.learnjava.Main</mainClass>
</transformer>
</transformers>
</configuration>
注意,Maven自带的标准插件例如compiler是无需声明的,只有引入其它的插件才需要声明。
下面列举了一些常用的插件:
- maven-shade-plugin:打包所有依赖包并生成可执行jar;
- cobertura-maven-plugin:生成单元测试覆盖率报告;
- findbugs-maven-plugin:对Java源码进行静态分析以找出潜在问题。
12 Nexuse
# 1 拉取镜像并启动
sudo docker run -d --restart always --name nexus3 \
-v nexus3_data:/sonatype-work \
-p 9081:8081 sonatype/nexus3
# 2 进入容器
docker ps
# sudo docker exec -it 容器ID /bin/bash
sudo docker exec -it 8132f5a920b7 /bin/bash
# 3 查看密码
more /nexus-data/admin.password
# 41d3f24b-fdc8-4149-8127-55c5ce1658b8
# 4 打开控制台 修改admin密码
http://localhost:9081/
13 Maven debug
# 开启debug
mvn -X 等效 --debug
mvn help:effective-settings
14 命令创建项目
# 创建java应用
mvn archetype:generate -DgroupId=com.companyname.bank -DartifactId=consumerBanking -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
# 创建web应用
mvn archetype:generate -DgroupId=com.companyname.automobile -DartifactId=trucks -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
15 常用命令汇总
# 基本命令
mvn -help
mvn -v //查看版本
mvn archetype:create //创建 Maven 项目
mvn compile //编译源代码
mvn test-compile //编译测试代码
mvn test //运行应用程序中的单元测试
mvn site //生成项目相关信息的网站
mvn package //依据项目生成 jar 文件
mvn install //在本地 Repository 中安装 jar
mvn -Dmaven.test.skip=true //忽略测试文档编译
mvn clean //清除目标目录中的生成结果
mvn clean compile //将.java类编译为.class文件
mvn clean package //进行打包
mvn clean test //执行单元测试
mvn clean deploy //部署到版本仓库
mvn clean install //使其他项目使用这个jar,会安装到maven本地仓库中
mvn archetype:generate //创建项目架构
mvn dependency:list //查看已解析依赖
mvn dependency:tree //看到依赖树
mvn dependency:analyze //查看依赖的工具
mvn help:system //从中央仓库下载文件至本地仓库
mvn help:active-profiles //查看当前激活的profiles
mvn help:all-profiles //查看所有profiles
# 强制maven下载最新的快照构
mvn clean package -U
# 跳过单元测试
-DskipTests # 不执行测试用例,但编译测试用例类生成相应的 class 文件至 target/test-classes 下
-Dmaven.test.skip=true # 不执行测试用例,也不编译测试用例类
mvn clean install -DskipTests -U
mvn clean -Dmaven.test.skip=true
# 开启debug
mvn deploy --debug
mvn deploy -X
# 用 4 个线程构建,以及根据 CPU 核数每个核分配 1 个线程进行构建
mvn -T 4 clean install
mvn -T 1C clean install
# 如果还是阻塞: 资源管理器 - shutdown all java app
# 编译失败后,接着编译
# 如果是 Apache Eagle 之类带有几十个子项目的工程,如果从头编译所有的模块,会很耗功夫
# 通过指定之前失败的模块名,可以继续之前的编译
mvn -rf :moduleName clean install
# 跳过失败的模块,编译到最后再报错
mvn clean install --fail-at-end
# 编译指定 module
mvn install -pl B -am
-pl, --projects (Build specified reactor projects instead of all project)
-am, --also-make (If project list is specified, also build projects required by the list)
# And this will build B and the moudules required by B
# 安装依赖
mvn dependency::tree
# 依赖列表
mvn dependency:list
# 依赖树(这里推荐直接用 Intellij Idea 中自带的 "Show Dependencies" 功能,可视化地展示依赖树 和 对应依赖冲突,并能够直接对 依赖树进行修剪)
mvn dependency:tree
# 依赖分析
mvn dependency:analyze
Unused declared dependencies 表示项目中未使用的,但显示声明的依赖
Used undeclared dependencies 表示项目中使用到的,但是没有显示声明的依赖
# 离线 build (offline)
mvn install -o
# 日志级别
mvn clean -Dorg.slf4j.simpleLogger.defaultLogLevel=error
# Generate Code for Antlr
mvn clean install -T 1C -DskipTests=true -Dorg.slf4j.simpleLogger.defaultLogLevel=error -B
# Maven Properties
mvn clean install -Dmy.property=propertyValue
# Maven Check Style
mvn clean install -Dcheckstyle.skip
# Pre-download
mvn dependency:go-offline
# Version-compare
mvn versions:compare-dependencies -DremotePom=org.apache.hbase:hbase:0.98.8-hadoop2 -DreportOutputFile=depDiffs.txt
# 打包jar
mvn clean install -B -e -U -Dmaven.repo.local=/home/juven/ci/foo-repo/
# 发布jar到私服
mvn clean deploy -B -e -U -Dmaven.repo.local=/home/juven/ci/foo-repo/
# 发布本地jar到私服 命令
mvn deploy:deploy-file -Dmaven.test.skip=true -Dfile=~/ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.4 -Dpackaging=jar -DrepositoryId=releases -Durl=http://192.168.0.168:8081/repository/maven-releases/
# 查看实际生效的pom&settimg信息
mvn help:effective-pom
# 下载源码JAR和javadocs
mvn dependency:sources -DdownloadSources=true -DdownloadJavadocs=true
# 分析项目的依赖信息:
mvn dependency:analyze
mvn dependency:tree
# 一些参数
使用-U参数: 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默认以天为单位检查更新,而持续集成的频率应该比这高很多。
使用-e参数:如果构建出现异常,该参数能让Maven打印完整的stack trace,以方便分析错误原因。
使用-Dmaven.repo.local参数:如果持续集成服务器有很多任务,每个任务都会使用本地仓库,下载依赖至本地仓库,为了避免这种多线程使用本地仓库可能会引起的冲突,可以使用-Dmaven.repo.local=/home/juven/ci/foo-repo/这样的参数为每个任务分配本地仓库。
使用-B参数:该参数表示让Maven使用批处理模式构建项目,能够避免一些需要人工参与交互而造成的挂起状态。
使用-X参数:开启DEBUG模式。
在持续集成服务器上使用怎样的 mvn 命令集成项目,这个问题乍一看答案很显然,事实上比较好的集成命令会稍微复杂些,下面是一些总结:
不要忘了clean: clean能够保证上一次构建的输出不会影响到本次构建。
使用deploy而不是install: 构建的SNAPSHOT输出应当被自动部署到私有Maven仓库供他人使用,这一点在前面已经详细论述。
使用-U参数: 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默认以天为单位检查更新,而持续集成的频率应该比这高很多。
使用-e参数:如果构建出现异常,该参数能让Maven打印完整的stack trace,以方便分析错误原因。
使用-Dmaven.repo.local参数:如果持续集成服务器有很多任务,每个任务都会使用本地仓库,下载依赖至本地仓库,为了避免这种多线程使用本地仓库可能会引起的冲突,可以使用-Dmaven.repo.local=/home/juven/ci/foo-repo/这样的参数为每个任务分配本地仓库。
使用-B参数:该参数表示让Maven使用批处理模式构建项目,能够避免一些需要人工参与交互而造成的挂起状态。
使用-X参数:开启DEBUG模式。
16 修改项目版本号
统一修改各子模块版本号。
16.1 自定义参数
通过build命令传参方式 设置新的版本号
1.自定义env.project.version变量
<groupId>org.mvn</groupId> <artifactId>mvn-dao-jar</artifactId> <version>${env.project.version}</version>2.构建命令在父项目执行:
mvn clean deploy -Denv.project.version=1.0.0-SNAPSHOT 或 mvn clean deploy -Dparams="hiip-user-api.version=0.44.1-SNAPSHOT" # 查看依赖树的版本是否修改成功 mvn dependency:tree -Dverboss -Dincludes=${project.groupId}:${project.artifactId}
16.2 使用插件
插件很多,此处使用versions-maven-plugin
插件 :
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> <version>2.7</version> <configuration> <generateBackupPoms>false</generateBackupPoms> </configuration> </plugin>构建命令:
mvn versions:set -DnewVersion=1.0.1 package
17 setting.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">
<localRepository>/Users/xxx/.m2/repository</localRepository>
<pluginGroups>
</pluginGroups>
<proxies>
</proxies>
<servers>
<server>
<id>libs-releases-local</id>
<username>xxx</username>
<password>xxx</password>
</server>
<server>
<id>libs-releases</id>
<username>xxx</username>
<password>xxx</password>
</server>
<server>
<id>libs-snapshots-local</id>
<username>xxx</username>
<password>xxx</password>
</server>
<server>
<id>plugins-releases-local</id>
<username>xxx</username>
<password>xxx</password>
</server>
<server>
<id>plugins-releases</id>
<username>xxx</username>
<password>xxx</password>
</server>
<server>
<id>plugins-snapshots-local</id>
<username>xxx</username>
<password>xxx</password>
</server>
</servers>
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<mirror>
<id>maven-xx</id>
<mirrorOf>central</mirrorOf>
<name>mirrors in xx</name>
<url>http://artifactory.xx.com/centra-repo1-cache</url>
</mirror>
</mirrors>
<profiles>
<profile>
<repositories>
<repository>
<id>libs-releases-local</id>
<name>libs-releases-local</name>
<url>http://artifactory.xx.com/libs-releases-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>libs-releases</id>
<name>libs-releases</name>
<url>http://artifactory.xx.com/libs-releases</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<snapshots />
<id>libs-snapshots-local</id>
<name>libs-snapshots-local</name>
<url>http://artifactory.xx.com/libs-snapshots-local</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>plugins-releases-local</id>
<name>plugins-releases-local</name>
<url>http://artifactory.xx.com/plugins-releases-local</url>
</pluginRepository>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>plugins-releases</id>
<name>plugins-releases</name>
<url>http://artifactory.xx.com/plugins-releases</url>
</pluginRepository>
<pluginRepository>
<snapshots />
<id>plugins-snapshots-local</id>
<name>plugins-snapshots-local</name>
<url>http://artifactory.xx.com/plugins-snapshots-local</url>
</pluginRepository>
</pluginRepositories>
<id>artifactory</id>
</profile>
<profile>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>ali</id>
<name>libs-releases-ali</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</repository>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>ali2</id>
<name>libs-releases-ali2</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<id>weixx</id>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>