本文讲述了在项目结构固定的情况下,如何不改变结构、不重建项目而后期将项目改变为maven项目并导出jar包,主要面向对maven一窍不通的新人。
1. 普通项目转为maven项目
首先,File->open打开一个项目文件夹,例如我打开下面这个test项目:
可由以下两种方式将其转为maven项目:
- 右键项目文件夹->Add Framework Support->勾选Maven->OK
- 在项目文件夹下新建一文件,重命名为pom.xml->在IDEA中右键pom.xml->Add as Maven Project
(使用第一种方法可能发现右键菜单里没有Add Framework Support,或者里面没有Maven,换用第二种方法就行。)
第一种方法会自动创建pom.xml并且添加必要的信息,并且在src里面创建main包,不过我们已经完成了项目的编写,这个包就没有存在的必要了。有关pom.xml的内容后面再讲
2. pom.xml
2.1 初始化
使用第一种方法创建pom.xml会自动加入一些必要信息
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
第一行是xml文件的声明,后面的 <project>...</project>
是xml的根标签,后面做的所有改动都需要在这个标签内进行。
其中,modelVersion标识了模型版本,maven 2或3可将其设置为4.0.0
后面三行的groupId-artifactId-version可简单理解为:谁的项目-项目名称-项目版本
2.2 依赖库的添加
在maven项目中,添加一个依赖库需要在pom.xml的 <project>
标签中添加一个 <depency>
标签。
若要添加多个依赖库,需在所有 <depency>
标签外添加 <depencies>
标签,结构如下:
<dependencies>
<dependency>
<!-- first depency -->
</dependency>
...
<dependency>
<!-- last depency -->
</dependency>
</dependencies>
添加 <depency>
标签可以前往mvnrepository查询所需库,选择对应版本,复制粘贴到pom.xml中即可。
例如现在我想添加Junit4.12,搜索Junit,选择使用最多的一项。
可以看到Junit的各个版本,点击我们需要的4.12版本,就可以看到相应的标签内容了,将其复制到pom.xml中就可以了。
(注:要将 <scope>test</scope>
标签删去,它指定了依赖范围,有compile,test,provided,runtime,system 五种状态,默认为compile,不删去的话在编译时无法使用该依赖)
2.3 构建环境
这部分( <project>
标签下的 <build>
标签)将指引maven构建项目。
2.3.1 指定源代码、测试代码目录
maven默认的源代码目录为src/main/java,测试代码目录为src/test/java,而我们的项目结构已经定型,直接编译打包的话会生成一个空包,提示Maven: No sources to compile,这时我们就需要添加标签,将其指向项目中的目录。
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
2.3.2 添加maven插件
Maven 实际上是一个依赖插件执行的框架,每个任务是由插件完成。
在 <build>
标签中添加 <plugins>
标签
2.3.2.1 compiler
编译 Java 源文件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source><!-- 源代码使用的JDK版本 -->
<target>1.8</target><!-- 需要生成的目标class文件的编译版本 -->
</configuration>
</plugin>
2.3.2.2 jar
将项目打包成jar包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>P1.test</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
其中只需要注意 <mainClass>
标签即可,它指定了jar包运行的主类,比如以上述标签打包,运行时就会第一个运行P1.test。它会写入到jar包中META-INF目录下的MANIFEST.MF文件中(main-Class: P1.test),打包后也可以手动进行更改。
(注:MANIFEST.MF中冒号后面一定要有一个空格)
2.3.2.3 assembly
用于将依赖库一同打入另一个jar包。
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>P1.test</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<mainClass>
标签功能与上面叙述的相同。
<descriptorRefs>
标签指定了带有依赖库的jar包的额外名字,例如我用mvn package打包生成的jar包名为a.jar,则使用mvn assembly:assembly命令打包生成的jar包就命名为a-jar-with-dependencies.jar。
2.4 更换镜像源
maven项目的构建需要把依赖库下载到本地仓库,可换用国内源增加下载速度。
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.5 中文编码
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
3. 导出jar包
双击右侧菜单栏中的package,或在命令行中输入命令 mvn package
,默认存放路径为target目录
注:在IDEA中操作与在命令行中操作结果可能有所不同,是因为在IDEA设置中(File->Settings->Build, Execution, Deployment->Build Tools->Maven)可以修改maven的配置文档位置,大部分网上的maven配置教程都会将这个位置修改成maven安装目录下的conf/settings.xml,而命令行中mvn使用的默认配置文件是用户文件夹下的.m2/settings.xml
4. 关于软件构造Lab1的分P打包
我个人的做法是在src中新建了一个包/类MainActivity,作用是根据命令行的输入决定执行P几的程序,并在pom.xml中生成jar包的mainClass设置为这个类。
而将三个部分分开打包我是手动操作的,先整体打包,结构如下:
对于每个单独的jar包,删除其他两个P以及MainActivity,只留下相应的包(P1, P2或P3),然后修改META-INF目录下的MANIFEST.MF,将其中的 Main-Class: MainActivity.MainActivity
分别修改为
Main-Class: P1.MagicSquare
Main-Class: P2.turtle.TurtleSoup
Main-Class: P3.FriendshipGraph
即可
5. 常用maven命令
mvn clean
清理编译结果mvn compile
编译mvn package
打包mvn assembly:assembly
带依赖库打包
6. 遇到过的问题
6.1 程序包org.junit不存在
删除 <depency>
标签中的 <scope>
标签
6.2 jar包为空
原因:没有指定源代码目录
在 <build>
标签中添加:
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
6.3 jar包中java文件没有编译成class导致的"找不到或无法加载主类"
原因:没有编译 在插件中添加compiler
6.4 .jar中没有主清单属性
原因:没有写入mainClass 见 2.3.2.2
Comments