文章目录
- Maven 项目编译 和 运行
- cmd 下编译 java 文件
- `pom.xml`与 文件目录结构 的关系
- 项目根目录名 vs. artifactId
- 源代码文件层级目录`main/java/com/xxxx/demo` vs. `pom.xml`中的 groupId vs. 源代码中 package
Maven 项目编译 和 运行
cmd 下编译 java 文件
- 编译 java 文件
在 cmd 下,进入项目的根目录(pom.xml
所在目录)
mvn compile
- 会从 远程仓库 下载依赖包到 本地仓库
- 第一次下载会比较慢,因为会把所需要的环境(包括未来其他项目会用到的依赖,如:junit、log4j等)统统都下载到本地仓库。之后再次执行
mvn compile
就快了。
- 会在 Maven 项目的根目录下生成 target 目录(Maven 项目打包输出目录)
- 如果修改了代码,需要重新编译,需要清除当前编译好的文件,可以使用
mvn clean
。该操作会删除该Maven项目的 target 目录,但不会对mvn compile
下载到本地仓库的依赖包进行删除。
cmd 中显示
BUILD SUCCESS
,则mvn compile
执行成功,maven 项目已经编译完成。
- 执行 main 方法
- 如果
.java
文件是放在 包(package)里的,即文件目录如:
com
|
|--- testmaven
|
|--- demo // 这个 demo 是一个包
|
|--- Hello.java
则 首先 Hello.java
文件里第一行要说明 package com.testmaven.demo
。
当 mvn compile
成功编译之后,执行
mvn exec:java -Dexec.mainClass="com.testmaven.demo.Hello"
不能省略前面的 com.testmaven
而只写 demo.Hello
,否则执行不成功。
- 如果
.java
文件是不放在包(package)里的,即文件目录如:
com
|
|--- testmaven
|
|--- demo // 这个 demo 是一个包
| |
| |--- Hello.java
|
|--- Hi.java // Hi.java 并没有放在 包里
则 首先 Hi.java
文件里第一行不能写package com.testmaven.demo
之类的包声明。
当 mvn compile
成功编译之后,执行
mvn exec:java -Dexec.mainClass="Hi"
不能写成 com.testmaven.Hi
(会导致执行不成功)。
注意看看下面的区别:
mvn exec:java -Dexec.mainClass="com.testmaven.demo.Hello"mvn exec:java-Dexec.mainClass="com.testmaven.demo.Hello"
前者正常执行。
后者报错:
Could not find goal 'java-Dexec.mainClass=com.testmaven.demo.Hello' in plugin org.codehaus.mojo:exec-maven-plugin:3.0.0 among available goals exec, help, java -> [Help 1]
就是因为漏了一个空格,排查了一上午都不知道问题在哪里,网上也找不到答案,一度以为是
pom.xml
与 目录结构的对应问题。吃一堑长一智。
pom.xml
与 文件目录结构 的关系
项目根目录名 vs. artifactId
其实 pom.xml
中的 artifactId 与 项目文件夹根目录名字是可以不同的,实测不会报错,正常编译执行。
mvn
命令编译、执行时,实际上以pom.xml
中的groupId
与artifactId
为准(如果与有冲突也是按为准),而非以项目文件目录结构中的根目录或目录层级名为准。
源代码文件层级目录main/java/com/xxxx/demo
vs. pom.xml
中的 groupId vs. 源代码中 package
其实文件层级的名,并不影响 mvn compile
的编译,也不影响mvn exec:java -Dexec.mainClass="com.testmaven.demo.Hello"
的执行。
pom.xml
中的 groupId 也不影响 mvn
可以对什么包编译执行。比如<groupId>
中为 com.testmaven
,main/java/com
目录下可以压根就不含testmaven
这个目录,而源代码中也可以压根不含 com.testmaven
打头的包声明。
而源代码中 package 的包声明,比如声明为 package com.haha.hey
,并不一定就要将该源代码放到 com/haha/hey
目录下,你甚至可以直接放到com
的外面,放到main/java/
下,mvn compile
对项目进行编译后,还是可以通过其包名.公共类名
来执行。如:
mvn exec:java -Dexec.mainClass="com.haha.hey.Waah"
影响执行的是源代码中 package 到底是怎么写的。写的是
package com.testmaven.demo
执行时就得是这个包名.公共类名
。如果没写,执行时就直接是公共类名
。
综上:
mvn
命令执行时,以pom.xml
中 的<groupId>
与<artifactId>
为准。不受文件层级名、项目跟目录名约束。mvn
运行 java 编译后的程序,只与 java 源代码中声明的包有关系,与该java源文件放在什么目录下无关。(当然该java源文件还是需要放在/src/main/java/内才行,再往外面就不行了。)- Maven 项目的目录层级结构的命名只是约定,并不强制。
pom.xml
才是关键。