- A+
原文地址:
https://iassas.com/archives/4afab831.html
在 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 压缩之后无法运行,我是通过直接解压缩 - 压缩 - 运行将这个问题定位出来的。
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫