0x0 Maven 简介
Maven是由Apache软件基金会开发的跨平台项目管理工具软件,基于Apache License 2.0协议发布,需JDK 8+运行环境,最新版本为2023年6月29日发布的3.9.3版。该工具起源于Jakarta Turbine项目的构建标准化需求,名称取自意第绪语"知识的积累",旨在解决Ant构建脚本差异化及JAR文件共享问题 [1] [4] [7]。
Maven通过项目对象模型(POM)实现项目构建、依赖管理和文档生成,提供标准化的生命周期流程(clean/default/site)及常用命令如mvn compile、mvn install等操作。其采用集中式信息管理机制,通过预定义构建规则简化项目配置,支持本地仓库依赖共享,核心功能包括构建生命周期定义、插件系统扩展及自动化依赖下载 [1] [5-6] [9]。该工具被广泛应用于Apache Jakarta项目及企业级Java项目开发,支持多模块项目管理,其3.x版本在保持与Maven 2向后兼容性的基础上优化了性能与可用性
类似于php的composer
0x1 依赖解析
在 XML 中,前缀是指标签名中冒号前面的部分,例如 xsi:schemaLocation 中的 xsi。如果标签名没有冒号,就是"没有前缀的标签"。
在你的 pom.xml 里,绝大多数标签(如 <groupId>、<artifactId>、<version>)都没有前缀。这是因为根元素 <project> 通过 xmlns="http://maven.apache.org/POM/4.0.0" 设置了默认命名空间,意思是:所有不带前缀的标签都属于这个 Maven POM 命名空间,它们遵循 Maven 定义的规范。
而像 xsi:schemaLocation 这样的标签带有前缀 xsi,它是通过 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 声明的另一个命名空间,专门用于 XML Schema 实例相关的属性(如提供模式位置)。
简单说:
· 没有前缀的标签 → 属于 Maven POM 标准,是 Maven 认识的核心配置(如项目坐标、依赖)。
· 有前缀的标签 → 属于其他命名空间,通常用于辅助功能(如校验、扩展属性)。
这种设计让 XML 可以在同一个文档中混合多个不同"词汇表",而不会互相冲突。
XML
<!-- 根元素,声明此文件是 Maven 项目描述符,指定命名空间和模式位置 -->
<!-- xmlns="http://maven.apache.org/POM/4.0.0" 这行定义了默认命名空间。
· 命名空间就是给标签加上一个"归属标识",防止不同 XML 格式里的同名标签(比如 name)冲突。
· 这个网址看起来像链接,但它其实只是一个唯一标识符,告诉别人:这个文件里所有没有前缀的标签(如 <groupId>)都是 Maven POM 规范中定义的标签。
· 好比说"这辆车是按照国家汽车标准制造的",那个标准编号就是命名空间。-->
<!-- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" 前半部分 http://maven.apache.org/POM/4.0.0 是命名空间。
· 后半部分 http://maven.apache.org/maven-v4_0_0.xsd 是一个实际可访问的 XSD 文件,它就像是"说明书",里面详细描述了哪些标签可以写、标签的先后顺序、数据类型等。
· IDE 或 Maven 会读取这个说明书来校验你的 pom.xml 格式是否正确,并提供代码提示。-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!-- · <modelVersion>4.0.0</modelVersion>
声明当前 POM 模型版本。对于 Maven 2 及 3,这个值必须是 4.0.0,表示使用该版本的 POM 规范。
· <groupId>com.jflyfox</groupId>
组织标识,通常采用反向域名的方式,确保全局唯一。它代表项目所属的组织或团队,例如 com.jflyfox 对应域名 jflyfox.com。
· <artifactId>jfinal_cms</artifactId>
项目标识,在 groupId 范围内唯一。通常与项目名称一致,例如这里的 jfinal_cms 表示 JFinal CMS 项目。
· <packaging>war</packaging>
打包方式,默认为 jar。war 表示最终输出为 Web 应用归档文件(.war),可部署到 Servlet 容器(如 Tomcat)。其他常见值有 pom(父项目)、jar(Java 库)。
· <version>5.1.0</version>
项目版本号,通常遵循语义化版本(如 主版本.次版本.修订版)。Maven 根据版本号处理依赖的版本管理和升级。
这四者(groupId、artifactId、version,加上可选的 packaging)共同构成 Maven 的项目坐标,用于在仓库中唯一标识该项目及其构建产物。在依赖声明中,正是通过这三个核心坐标来引用其他构件。
方便别人引用,告诉Maven你是谁,是之前传上去了,这是个标签。
-->
<modelVersion>4.0.0</modelVersion>
<groupId>com.jflyfox</groupId>
<artifactId>jfinal_cms</artifactId>
<packaging>war</packaging>
<version>5.1.0</version>
<!-- 控制行为 -->
<!-- <properties>自定义属性-->
<properties>
<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<!-- 阿里连接池 -->
<druid.version>1.1.20</druid.version>
<!-- jfinal -->
<jfinal.version>4.7</jfinal.version>
<!-- mysql -->
<mysql.version>8.0.18</mysql.version>
<!-- beetl -->
<beetl.version>3.0.13.RELEASE</beetl.version>
<!-- fastjson -->
<fastjson.version>1.2.62</fastjson.version>
</properties>
引用
<dependencies>依赖标签
<dependencies>
<dependency>
来自组织
<groupId>com.jfinal</groupId>
项目名
<artifactId>jfinal</artifactId>
版本号
<version>${jfinal.version}</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>${jfinal.version}</version>
<classifier>sources</classifier>
</dependency>
<!-- <dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>1.58</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.7.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>1.58</version>
排除配置,排除子依赖
<exclusions>
<exclusion>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>cos</artifactId>
<version>26Dec2008</version>
</dependency>
<!-- aliyun oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>${beetl.version}</version>
</dependency>
<!-- <dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.2</version>
</dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<!-- 使用aliyun maven -->
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
远程下载
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</repository>
</repositories>
如何打包,目录映射
<build>
<!-- 打包目录 -->
<directory>target</directory>
<!-- 打包名称 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- java8 保留参数名编译参数 -->
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<targetPath>WEB-INF/classes</targetPath>
<directory>src/main/resources</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.3.v20120416</version>
<configuration>
<stopPort>9966</stopPort>
<stopKey>foo</stopKey>
<scanIntervalSeconds>0</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>80</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webAppConfig>
<contextPath>/${project.artifactId}</contextPath>
</webAppConfig>
<classesDirectory>${basedir}/target/${project.artifactId}/classes</classesDirectory>
<webAppSourceDirectory>${basedir}/target/${project.artifactId}</webAppSourceDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<port>80</port>
<path>/${project.artifactId}</path>
<!-- <warSourceDirectory>${basedir}/target/${project.artifactId}</warSourceDirectory>-->
</configuration>
</plugin>
</plugins>
</build>
</project>
0x2 报错
XML
//org.apache.maven.plugins:maven-compiler-plugin:3.15.0:compile 无法从仓库下载
//未能达成目标
//无法解析插件
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.15.0:compile (default-compile) on project jfinal_cms: Execution default-compile of goal org.apache.maven.plugins:maven-compiler-plugin:3.15.0:compile failed: Plugin org.apache.maven.plugins:maven-compiler-plugin:3.15.0 or one of its dependencies could not be resolved:
//下载失败
//No PSK available. Unable to resume. 缺失密钥,网络不稳定
[ERROR] Could not transfer artifact org.codehaus.plexus:plexus-compiler-manager:jar:2.16.2 from/to central (https://repo.maven.apache.org/maven2): No PSK available. Unable to resume.
//
[ERROR] Could not transfer artifact org.codehaus.plexus:plexus-compiler-javac:jar:2.16.2 from/to central (https://repo.maven.apache.org/maven2): peer not authenticated
[ERROR]
//帮助
[ERROR] -> [Help 1]
[ERROR]
//
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
//如果想启用完整的调试日志(显示每个步骤的详细信息),可以加上 -X 参数重新运行。
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
//提供了一个官方 Wiki 链接,专门解释"插件解析异常"的常见原因和解决方法。
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException
0x3 正确
配置 Maven 全局镜像(settings.xml)
Maven 的 settings.xml 文件用于配置全局镜像、代理等。你需要找到或创建这个文件,并添加阿里云镜像。
1.找到 settings.xml 的位置
全局配置:Maven 安装目录下的 conf/settings.xml(例如 D:\apache-maven-3.8.8\conf\settings.xml)
用户配置(推荐):C:\Users\你的用户名\.m2\settings.xml(如果不存在,新建一个)
XML
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jflyfox</groupId>
<artifactId>jfinal_cms</artifactId>
<packaging>war</packaging>
<version>5.1.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<druid.version>1.1.20</druid.version>
<jfinal.version>4.7</jfinal.version>
<mysql.version>5.1.49</mysql.version>
<beetl.version>3.0.13.RELEASE</beetl.version>
<fastjson.version>1.2.62</fastjson.version>
<maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
<maven.surefire.plugin.version>2.22.2</maven.surefire.plugin.version>
<maven.resources.plugin.version>3.1.0</maven.resources.plugin.version>
<maven.war.plugin.version>3.2.2</maven.war.plugin.version>
</properties>
<dependencies>
<!-- JFinal 核心及源码 -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>${jfinal.version}</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>${jfinal.version}</version>
<classifier>sources</classifier>
</dependency>
<!-- Servlet & JSP API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>cos</artifactId>
<version>26Dec2008</version>
</dependency>
<!-- 序列化 -->
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>1.58</version>
<exclusions>
<exclusion>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 缓存 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.7.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- XML 解析 -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 阿里云 OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.0.6</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>${beetl.version}</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</repository>
</repositories>
<build>
<directory>target</directory>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<!-- 资源插件(确保编码) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven.resources.plugin.version}</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 测试插件(指定稳定版本,避免自动下载最新) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
</plugin>
<!-- WAR 打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<targetPath>WEB-INF/classes</targetPath>
<directory>src/main/resources</directory>
</resource>
</webResources>
</configuration>
</plugin>
<!-- Jetty 插件(开发调试用) -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.3.v20120416</version>
<configuration>
<stopPort>9966</stopPort>
<stopKey>foo</stopKey>
<scanIntervalSeconds>0</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>80</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webAppConfig>
<contextPath>/${project.artifactId}</contextPath>
</webAppConfig>
<classesDirectory>${basedir}/target/${project.artifactId}/classes</classesDirectory>
<webAppSourceDirectory>${basedir}/target/${project.artifactId}</webAppSourceDirectory>
</configuration>
</plugin>
<!-- Tomcat 插件(可选) -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<port>80</port>
<path>/${project.artifactId}</path>
</configuration>
</plugin>
</plugins>
</build>
</project>