本文使用场景:
- 使用 Eclipse 导出 Java jar包,包括导出的jar包含第三方jar
- 导出的jar文件能够读取jar包外部的配置文件
Java导出 jar 文件的方式有
- 1.只是将自己写的代码打jar包
- 2.导出的jar包含第三方jar包
- 3.导出的jar需要读取jar外部的配置文件
对于第一种情况:只是将自己写的代码打包为 jar ,这种情况一般是将自己写的工具类封装打包,以便以后方便自己使用
操作如下:
在 Eclipse 工作空间右键项目 — Export — 在弹出的对话框中选择 jar file — 然后点击 next
接下来只选择 所需要的类文件就可以了,不选.classpath和.project,选择好需要导出的类文件之后,在“Select the export destination ”这一栏选择导出的 jar路径以及名称
选择好之后,点击“next”进入下一步
这一步不需要操作,接着下一步
最后一步,在”Specify the manifest:(指定声明)” 这一栏选择“Generate the manifest file (生成声明文件)”,下边的两项”Seal contents”和”Main class”不用管,然后直接点击”finish”完成
点击”finish”完成之后,会弹出一个警告对话框,不用管它,jar包已经导出完成。
这是第一种的 只是将自己的代码导出jar ,相当于一个类库,以后自己使用起来比较方便。
使用示例:
接下来要说的是 如果你写的程序里边使用了第三方类库,即你所导出的jar文件里边引用的有第三方jar ,那么,你在使用你自己导出的jar包时候,你就需要将你源程序引用的jar也要导入的新的项目里边来,也就是要有依赖jar包,这样,你的程序才能正常运行。
运行示例:
没有将依赖jar包导入项目,会抛出” ClassNotFoundException “异常,解决办法: 将依赖jar包导入项目
测试示例:
测试程序的功能为统计一个文件的总行数
以上导出jar包的方式已经满足开发者的需要了,但是,并非所有导出的jar包都是给开发者使用的,比如会有这样的需求,要求: Java导出可运行jar包,但是这个可运行jar包中的程序引用了第三方jar,而且还有配置文件 现在要求是这样的“ 配置文件要放在jar包外,但是程序能够读取到 ”这样做的目的是便于修改配置,总不能让客户将jar包解压,然后再做修改吧(我测试了下jar包内的Java源码是看不到的,但是配置文件可以看到,而且还能修改)
有了这个需求,接下来就是实现这个功能:
这一次在打包之前,需要先做点东西,先在项目根目录下创建一个文件夹 (Folder),然后将依赖的jar包复制到里边,再在这个目录下边创建一个名为”MANIFEST.MF”的文件(File)
MANIFEST.MF 文件里边写这些东西:
Manifest-Version: 1.0
Class-Path: lib/log4j-1.2.17.jar
Main-Class: com.ancun.client.FileDownloader
第一行”Manifest-Version”代表版本号,这个无所谓,写个1.0吧
第二行“Class-Path”里边写你的程序引用的第三方jar,注意,是在这个项目中的相对路径
第三行“Main-Class”指定你的主程序,确定你这个打包的jar文件从哪个类里边开始运行,格式:包名+类名(这个类里边要有main方法)
注意事项:
第一,这是 4 行代码,最后一行什么不写,但是必须要有,否则,打包之后你会发现少了一行;
第二,每个冒号(:) 后边都必须有空格,如果引用了多个第三方jar,则jar包之间也是用空格隔开
OK,准备工作做好之后,就可以开始打jar包了,还是和原来一样,右键项目 — 导出(Export) — 选择”jar file” — 选择要导出的程序,一切按部就班
然后点击下一步(Next) ,再下一步(Next),到了完成(Finish)的界面,这里就和上一次的不一样了,看图:
从工作空间中选择”MANIFEST”文件,然后选择要导出的项目,找到 MANIFEST.MF 文件,然后选中,点击”Finish”完成
至此,打包工作已经完成,但是这并不意味着你可以直接来运行你所导出的jar包,还有一些后续工作要做
在做后续工作之前,我们再来看一遍需求,需求里边是要求配置文件不在jar包中,但是,jar包内的程序可以读取到jar包外的配置文件,这个怎么实现呢 ?我们来看程序
源码如下(读取配置文件部分):
private static Logger logger = Logger.getLogger(FileDownloader.class);
static{
try {
// 读取配置文件
PropertyConfigurator.configure(System.getProperty("user.dir") + "/config/log4j.properties");
logger.debug("Path: " + System.getProperty("user.dir"));
} catch (Exception e) {
logger.error("FileNotFound: " + e.toString());
}
}
为什么要这么写?通常情况下,将“log4j.properties” 配置文件直接放在 src 目录下是可以不用再程序里边在写从哪里读取配置文件的,程序默认从这里读取,但是因为你这是要 导出jar包,并且将jar包和配置文件分离 ,所以你需要这么做,程序的意思是 先读取项目的绝对路径,然后在从绝对路径中拼出配置文件的路径 ,这样做的好处是你在项目里边可以找到配置文件并读取,将项目打包之后,程序依然可以读取到配置文件
我们需要在导出的jar包目录下创建我们刚才配置的一些信息,比如,在jar包同目录下创建”lib”文件夹,然后将引用的第三方jar包拷贝进去,这时,程序就可以正常运行了,对于那些不需要读取配置文件的同学来说,到这里,导出包含第三方jar包的jar包 工作已经完成了(这句话读起来有点拗口啊)
对于还需要jar包内的程序读取jar包外的配置文件的同学来说,还需要在导出的jar包的同一目录下创建一个”config”文件夹(这个文件夹的名称根据程序里边写的来定,程序里边写的文件目录是”config”,这里就写”config”),然后在将配置文件拷贝到里边来,如图:
配置文件如下(上源码):
log4j.rootLogger=debug, toConsole,toFile
log4j.appender.file.encoding=UTF-8
log4j.appender.toConsole=org.apache.log4j.ConsoleAppender
log4j.appender.toConsole.Target=System.out
log4j.appender.toFile.Append=true
log4j.appender.toFile.Threshold=debug
log4j.appender.toConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.toConsole.layout.ConversionPattern=%d %p [%t] %C.%M(%L) | %m%n
# type the log file path
log4j.appender.toFile.file=e://test/log.log
#Daily one log file
log4j.appender.toFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.toFile.Append=true
log4j.appender.toFile.Threshold=info
log4j.appender.toFile.layout=org.apache.log4j.PatternLayout
log4j.appender.toFile.layout.ConversionPattern=%d-%p %t %C.%M(%L) | %m%n
log4j.appender.toFile.DatePattern='.'yyyy-MM-dd'.log'
关于 log4j配置文件 的信息不是本篇的关注点,这里我们只看这一行
log4j.appender.toFile.file=e://test/log.log
这句话的意思就是指定了日志的输位置
到这里,Java导出jar包,并且让jar包内程序读取jar包外配置文件 的操作说明已经全部完成,为了让读者能够更加快速直观地看到效果,我在这里直接贴出演示结果:
双击jar包直接运行(前提是你的电脑已经安装了jre,并且配置好了系统环境变量)
为了演示好看,我做了一个可视化界面,看图,当程序(jar包)运行起来之后,日志文件(log.log)已经生成了,让程序接着跑
日志已经出来了(日期解释一波:晚上跑的程序,第二天写的博客,要知道写博客很花时间的)
我们再来看结果
最后,再上一张使用命令行运行jar包的截图(图中包含如何使用命令行运行jar包, 细心的读者也可以对比一下命令行下(控制台)输出的日志和保存在文件中的日志的区别)
OK,这就是全部了。