jar文件打包成app
在Mac上运行jar文件(例如Behinder)每次都需要
1 | java -XstartOnFirstThread -jar Behinder.jar |
,感觉太繁琐了。因此,想打包成app方便使用。成功打包效果图如下,这里给大家提供打包出来的app。
链接:https://pan.baidu.com/s/1474CrgbbSfbXxqJGg9carA 密码:f9vm
使用工具可方便的将jar文件打包成app,本文以Behinder为例,记录所遇到的问题以及如何处理。
前期准备
下载jar2app之后,将其安装。
1 | # Install |
生成APP
通过jar2app的命令我们可以得知,直接使用对应命令即可生成。其中需要注意以下两点:
- Behinder需要通过
-XstartOnFirstThread
命令启动; - Behinder需要jre6~jre8版本才可以运行。
因此我在使用jar2app时,指定了JVM设置和JDK版本。
1 | jar2app Behinder.jar -j "-XstartOnFirstThread" -r /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk |
使用上面的命令可以成功生成一个app,但是直接运行无法打开。
问题排查
直接打开Behinder.app/Contents/MacOS/JavaAppLauncher启动脚本,提示数据库文件丢失,无法启动。
数据库文件丢失
根据报错信息提示以及Behinder本身的文件结构,我将data.db移动到Behinder.app/Contents和其他杂七杂八的位置都不行。
1 | Contents/data.db |
重构class文件
根据报错信息(数据库文件丢失)以及上述所进行的测试方法,基于当前的情况,只能通过将jar包文件反编译成class文件进行查看,判断本身源码逻辑。这里我采用JD进行反编译,直接加载Behinder的jar包文件。根据关键字:data.db进行搜索。
根据上图可以看到对应判断的逻辑在:net/rebeyond/behinder/core/ShellManager.class文件中:
1 | if (!new File("data.db").exists()) { |
通过File().exists()进行判断文件是否存在,根据大佬的提示得知File().exists()使用的user.home作为路径,将其修改成File.getAbsoluteFile()即可成功。
在JD将ShellManager.class保存成java代码,使用Intellij创建一个项目。Ps:也可以用eclipse等。
这里我新建了一个Maven项目,Project SDK选择1.8.0
下面有关字段全部设置成Behinder
将ShellManager.java文件拖入到src/main/java目录下,并将File().exists()修改成File().getAbsoluteFile().exists()。
新建一个package,右键java目录new即可创建,目录名称为net.rebeyond.behinder.core。该名称来源为ShellManager在Behinder.jar文件中的路径。将ShellManager.java文件移动到net.rebeyond.behinder.core中。
此时还有一系列包引入问题待解决,这时候点击【File】选项中的【Project Structure】功能,在【Project Settings】中的【Modules】的【Dependencies】中引入Behinder.jar文件。
这时候还存在模块无法import的问题,根据查看发现是json模块无法引入,查看JD中json包是20180130的。在jar-download页面进行下载即可,下载完成之后,按照刚刚的流程导入。导入完成之后,这时候已经所有包都正常import。
使用【Build Project】将java文件编译成class文件。
解压Behinder.jar文件,将解压出来的ShellManager.class文件替换成新编译出来的ShellManager.class文件。替换完成之后,使用压缩软件将其压缩成zip。将文件后缀修改成jar,在终端下运行,看能否成功运行。Ps:记得在Behinder.jar文件同级目录需要有一个data.db;这里有个问题,我用BetterZip将其压缩成zip之后,修改后缀无法运行,使用BandiZip(Windows)压缩可以,猜测有可能是软件压缩机制或者操作系统的问题。也可以使用jar命令进行打包。
1 | jar -cfm Behinder.jar ./META-INF/MANIFEST.MF ./* |
1 | java -XstartOnFirstThread -jar Behinder.jar |
可以成功运行,在使用jar2app命令将其打包成app
1 | jar2app Behinder.jar -j "-XstartOnFirstThread" -r /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk |
将data.db文件移动到Behinder.app/Contents即可成功运行。
生成带有图标的APP
上面生成的app是没有图标的,jar2app有-i参数支持图标生成。直接将Behinder.jar文件的net/rebeyond/behinder/resource目录下的logo.jpg拿出来。使用ICON在线转换,这里需要注意的是下载的文件格式应该为icns,并非是icon。
使用如下命令即可生成一个带有logo图标的Behinder.app文件。
1 | jar2app Behinder.jar -j "-XstartOnFirstThread" -r /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk -i logo.icns |
总结
这里面踩了无数个坑,反反复复好长一段时间才解决。
- 工具记得多读手册,例如在这里用的jar2app直接在GitHub上面多读手册,基本问题都能解决;
- 实现同样功能的不同函数,在使用时需要按照需求进行使用。例如这里的File().exists()与File.getAbsoluteFile(),不同函数名总有会不一样的地方,直接平时只是为了实现功能而忽略其本质,有时候出现问题的时候需要深入了解其本质;
- 在处理问题过程中使用到软件工具出现问题时,可不进行任何修改重复使用软件进行问题定位。例如这里的BetterZip压缩之后无法运行,我是通过直接解压缩-压缩-运行将这个问题定位出来的。