Maven程序打包配置
目标
- 程序通过脚本(win下
.bat
,*inux下.sh
)直接运行. - 程序输出可执行
jar
包. - 打包后的目录结构
├── bin
│ ├── start and other script...
├── conf
│ ├── config files...
├── lib
│ ├── library jars...
│ ├── runnable jar...
├── logs
└ └── log files...
工具及环境
- Eclipse
- Maven
- Maven插件:maven-jar-plugin
- Maven插件:maven-assembly-plugin
步骤
通过maven管理工具实现可运行的jar.
可执行jar包与普通jar包的根本性的区别是由于其jar包中的描述文件META-INF/MANIFEST.MF
(暂且我称之为描述文件,因为不知道官方的称呼\^_^)。
可执行的jar包其描述文件会包含Main-Class:
属性,指定了当执行java -jar
时执行那个类中的main
方法。
还可以在描述文件中通过Class-Path:
属性指明该jar包classpath
信息(用于包含其依赖的第三方库)。
NOTE:通过java -jar
命令运行java程序时-classpath
或者-cp
命令已经无效
因为使用了 -jar 选项,环境变量 CLASSPATH 和在命令行中指定的所有类路径都被 JVM 所忽略一个可执行的 JAR 必须通过 menifest 文件的头引用它所需要的所有其他从属 JAR。如果使用了 -jar选项,那么环境变量 CLASSPATH 和在命令行中指定的所有类路径都被 JVM 所忽略。
详细可参考http://www.ibm.com/developerworks/cn/java/j-jar/index.html通过maven打包可执行的jar文件首先执行项目的打包类型为
package
,在pom.xml
的<project>
节点,也就是根节点指定打包类型.
<packaging>jar</packaging>
- 通过
maven-jar-plugin
插件添加classpath
信息。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- 排除的配置文件 -->
<excludes>
<exclude>log4j2.xml</exclude>
<exclude>mongodb.properties</exclude>
<exclude>dbcp.properties</exclude>
</excludes>
<archive>
<manifest>
<!-- 指定主类 -->
<mainClass>com.kexion.wireless.xx.xx</mainClass>
<!-- 添加依赖到classpath -->
<addClasspath>true</addClasspath>
<useUniqueVersions>false</useUniqueVersions>
</manifest>
</archive>
</configuration>
</plugin>
- 通过
maven-assembly-plugin
插件指明项目组装打包输出,assembly.xml描述文件配置:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>package</id>
<formats>
<!-- 打包格式 -->
<format>zip</format>
</formats>
<!-- 不包含根目录 -->
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!-- 将指定项目中的目录输出到指定打包目录-->
<fileSet>
<directory>src/bin</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>start.sh</include>
</includes>
<!-- 指定文件权限(\*inux) -->
<fileMode>755</fileMode>
<!-- 过滤文件中的maven变量为maven值 -->
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>src/bin</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>start.bat</include>
</includes>
<!-- 过滤文件中的maven变量为maven值 -->
<filtered>true</filtered>
</fileSet>
<!-- 指定可配置文件到conf目录 -->
<fileSet>
<directory>src/main/resources</directory>
<excludes>
<exclude>spring.xml</exclude>
</excludes>
<outputDirectory>conf</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<!-- 指定依赖存放的位置 -->
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
上述配置文件中的<filtered>true</filtered>
作用是对其他文件中出现的maven变量进行转换,如在start.sh
文件中有如下内容,${project.build.finalName}
会替换成最终生成的jar包的名称。
#start.sh
RUNJAR=$EARLYWARNING_HOME/lib/${project.build.finalName}.jar
编写启动脚本
程序通过脚本启动,在脚本中判断程序所在的位置,并据此指明日志位置(由于暂时没有研究log4j是如何对配置文件中
fileName="logs/info.log"
起始位置的判断(默认情况下会在执行java -jar
命令的目录作为起始目录创建日志文件),所以暂时只能通过脚本指明日志文件位置)Bash
#!/bin/bash
#create by neo
#获取执行上一级目录,目的是为了获取程序的根目录
EARLYWARNING_HOME=$(dirname $(pwd))
LOG4J_LOGPATH=$EARLYWARNING_HOME/logs
CONFPATH=$EARLYWARNING_HOME/conf
RUNJAR=$EARLYWARNING_HOME/lib/${project.build.finalName}.jar
#some properties which need by app
PROPERTIES_LOG4J_LOGPATH=log4j.logPath
#run!
#命令结尾的`&`表示后台运行程序
java -Xbootclasspath/a:$CONFPATH -D$PROPERTIES_LOG4J_LOGPATH=$LOG4J_LOGPATH -jar $RUNJAR &
- bat
@echo off
set CURRENT=%cd%
cd ..
SET EARLYWARNING_HOME=%cd%
cd %CURRENT%
set LOG4J_LOGPATH=%EARLYWARNING_HOME%\logs
set CONFPATH=%EARLYWARNING_HOME%\conf
set RUNJAR=%EARLYWARNING_HOME%/lib/${project.build.finalName}.jar
rem some properties which need by app
set PROPERTIES_LOG4J_LOGPATH=log4j.logPath
rem run!
@echo on
@java -Xbootclasspath/a:%CONFPATH% -D%PROPERTIES_LOG4J_LOGPATH%=%LOG4J_LOGPATH% -jar %RUNJAR%