Maven生成可以直接运行的jar包的多种方式(转)
转自:https://blog.csdn.net/xiao__gui/article/details/47341385
Maven可以使用mvn package指令对项目进行打包,如果使用java -jar xxx.jar执行运行jar文件,会出现"no main manifest attribute, in xxx.jar"(没有设置Main-Class)、ClassNotFoundException(找不到依赖包)等错误。
要想jar包能直接通过java -jar xxx.jar运行,需要满足:
1、在jar包中的META-INF/MANIFEST.MF中指定Main-Class,这样才能确定程序的入口在哪里;
2、要能加载到依赖包。
使用Maven有以下几种方法可以生成能直接运行的jar包,可以根据需要选择一种合适的方法。
方法一:使用maven-jar-plugin和maven-dependency-plugin插件打包
在pom.xml中配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxg.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
maven-jar-plugin用于生成META-INF/MANIFEST.MF文件的部分内容,<mainClass>com.xxg.Main</mainClass>指定MANIFEST.MF中的Main-Class,<addClasspath>true</addClasspath>会在MANIFEST.MF加上Class-Path项并配置依赖包,<classpathPrefix>lib/</classpathPrefix>指定依赖包所在目录。
例如下面是一个通过maven-jar-plugin插件生成的MANIFEST.MF文件片段:
Class-Path: lib/commons-logging-1.2.jar lib/commons-io-2.4.jar
Main-Class: com.xxg.Main
只是生成MANIFEST.MF文件还不够,maven-dependency-plugin插件用于将依赖包拷贝到<outputDirectory>${project.build.directory}/lib</outputDirectory>指定的位置,即lib目录下。
配置完成后,通过mvn package指令打包,会在target目录下生成jar包,并将依赖包拷贝到target/lib目录下,目录结构如下:
指定了Main-Class,有了依赖包,那么就可以直接通过java -jar xxx.jar运行jar包。
这种方式生成jar包有个缺点,就是生成的jar包太多不便于管理,下面两种方式只生成一个jar文件,包含项目本身的代码、资源以及所有的依赖包。
方法二:使用maven-assembly-plugin插件打包
在pom.xml中配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>com.xxg.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
打包方式:
mvn package assembly:single
打包后会在target目录下生成一个xxx-jar-with-dependencies.jar文件,这个文件不但包含了自己项目中的代码和资源,还包含了所有依赖包的内容。所以可以直接通过java -jar来运行。
此外还可以直接通过mvn package来打包,无需assembly:single,不过需要加上一些配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>com.xxg.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
其中<phase>package</phase>、<goal>single</goal>即表示在执行package打包时,执行assembly:single,所以可以直接使用mvn package打包。
不过,如果项目中用到Spring Framework,用这种方式打出来的包运行时会出错,使用下面的方法三可以处理。
方法三:使用maven-shade-plugin插件打包
在pom.xml中配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.xxg.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
配置完成后,执行mvn package即可打包。在target目录下会生成两个jar包,注意不是original-xxx.jar文件,而是另外一个。和maven-assembly-plugin一样,生成的jar文件包含了所有依赖,所以可以直接运行。
如果项目中用到了Spring Framework,将依赖打到一个jar包中,运行时会出现读取XML schema文件出错。原因是Spring Framework的多个jar包中包含相同的文件spring.handlers和spring.schemas,如果生成一个jar包会互相覆盖。为了避免互相影响,可以使用AppendingTransformer来对文件内容追加合并:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.xxg.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven生成可以直接运行的jar包的多种方式(转)的更多相关文章
- Maven生成可以直接运行的jar包的多种方式
Maven可以使用mvn package指令对项目进行打包,如果使用Java -jar xxx.jar执行运行jar文件,会出现"no main manifest attribute, in ...
- Maven生成可以直接执行的jar包
要想jar包能直接通过java -jar xxx.jar运行,需要满足: 1.在jar包中的META-INF/MANIFEST.MF中指定Main-Class,这样才能确定程序的入口在哪里: 2.要能 ...
- hadoop:将WordCount打包成独立运行的jar包
hadoop示例中的WordCount程序,很多教程上都是推荐以下二种运行方式: 1.将生成的jar包,复制到hadoop集群中的节点,然后运行 $HADOOP_HOME/bin/hadoop xxx ...
- Maven把项目依赖的所有jar包都打到同一个jar中
目录 1 使用maven-shade-plugin 2 推荐: 使用maven-assembly-plugin 3 扩展: Maven安装本地jar包到本地仓库 4 扩展: 手动生成jar包 5 扩展 ...
- 将 java 项目打包成可运行的 jar 包(main 函数带参数),并上传到 linux 服务器上运行
一.概述 java项目有两种架构,一种是 B/S 架构的,一种是 C/S 架构的. 对于 B/S 架构来说,我们常见的 java ee 即是 B/S 架构,通常,开发人员会在本地进行开发,然后将项目打 ...
- 分享:根据webservice WSDL地址自动生成java调用代码及JAR包
分享:根据webservice WSDL地址自动生成java调用代码及JAR包使用步骤:一.安装java 并配置JAVA_HOME 及 path二.安装ANT 并配置ANT_HOME三.解压WsdlT ...
- Eclipse下新建Maven项目、自动打依赖jar包
当我们无法从本地仓库找到需要的构件的时候,就会从远程仓库下载构件至本地仓库.一般地,对于每个人来说,书房只有一个,但外面的书店有很多,类似第,对于Maven来说,每个用户只有一个本地仓库,但可以配置访 ...
- Spring导出可以运行的jar包
最近需要解决Maven项目导入可执行的jar包的问题,如果项目不包含Spring,那么使用mvn assembly:assembly即可,详情可以参考:http://www.cnblogs.com/l ...
- Ant打包可运行的Jar包(加入第三方jar包)
本章介绍使用ant打包可运行的Jar包. 打包jar包最大的问题在于如何加入第三方jar包使得jar文件可以直接运行.以下用一个实例程序进行说明. 程序结构: 关键代码: package com.al ...
随机推荐
- (3.3)狄泰软件学院C++课程学习剖析四
对课程前面40课的详细回顾分析(二) 1.一个类的成员变量是对于每个对象专有的,但是成员函数是共享的. 2.构造函数只是决定一个对象的初始化状态,而不能决定对象的诞生.二阶构造人为的将初始化过程分为了 ...
- Linux相关基础知识
文件目录 /bin 放置系统执行档的目录,指令可被root与一般账户所使用. /boot 放置开机使用到的文档,包括linux核心档案,开机选单与所需设定档. /dev 任何装置与周边设备都是以档案的 ...
- [CSP-S模拟测试]:连连看(图论+容斥)
题目传送门(内部题74) 输入格式 输入文件$link.in$ 第一行三个整数$n,m,k$,之间用空格隔开,$n,m$表示地图行数和列数,$k$表示每个方块周围相邻的位置(至多有$4$个,至少有$2 ...
- java中 使用输入+输出流对对象序列化
对象: 注意记得实现 Serializable package com.nf147.sim.entity; import java.io.Serializable; public class News ...
- Java 实现 对象和转字符串之间的互转 (json格式)
添加依赖: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId> ...
- 洛谷P4127同类分布
传送 我们要在dfs的板子里记录哪些量呢?当前填的所有数的和sum?当前填的数构成的数值all? sum可以留下,数值就扔掉叭.数值最大是1e18,要是留下,在g数组里有一维的大小是1e18.也许可以 ...
- PJSIP库设置Via地址
好记性不如烂笔头,解决项目问题,调试代码跟踪到PJSIP 设置Via地址位置,记录下来,以备后用. PJSIP库在方法stateless_send_transport_cb中设置Via地址值,该方法在 ...
- VMware vMotion 配置要求
目录 目录 vCenter 支持 vMotion 的前提 条件 vMotion 的主机配置 vMotion 共享存储器要求 vMotion 网络要求 最后 vCenter 支持 vMotion 的前提 ...
- Caffe:深入分析(怎么训练)
main() 首先入口函数caffe.cpp int main(int argc, char** argv) { ...... ) { #ifdef WITH_PYTHON_LAYER try { # ...
- 倾旋之slack主题协同
源:https://pocketcorp.slack.com/join/shared_invite/enQtNTk2MDYwNDA4NzU0LTg3ZGVlNDE5NWUzNjJhZTc1MDQ5MT ...