Java程序的打包发布
Java程序的打包发布
文章目录
前言
Java以其跨平台性好、复用性强而被开发者普遍欢迎,是当前世界上最重要、最广泛使用的计算机语言。Java程序开发完成后,也需要和使用其他语言开发的应用程序一样,将普通人难以理解的计算机源码编译合成为可执行文件、打包为用户能够简单执行的安装包、发布为普通人能够理解并使用的软件产品。但是,由于Java的跨平台性是建立在Java虚拟机(JVM)的条件之上,Java程序打包时一般无法直接生成.exe(Windows) .app(Mac)等操作系统平台能够直接识别并运行的应用程序,因此Java软件发布的过程与其他软件不同,较为复杂。本文旨在总结Java程序打包的方法和流程。
A. 打包为.jar
1.什么是.jar
JAR文件(Java Archive,Java归档)是一种软件包文件格式,通常用于聚合大量的Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便开发Java平台应用软件或库。
JAR文件是一种归档文件,以ZIP格式构建,以.jar为文件扩展名。用户可以使用JDK自带的jar命令创建或提取JAR文件。也可以使用其他zip压缩工具,不过压缩时zip文件头里的条目顺序很重要,因为Manifest文件常需放在首位。JAR文件内的文件名是Unicode文本。
一般来说,JAR文件也是一种可执行文件,可以作为Java项目构建得到的软件成品。但是其运行必须要求计算机已经装有完整的Java虚拟机(JVM),否则无法运行。因此,将软件打包为JAR文件一般只是软件产品生成的第一步,后续还需要补充运行环境等其他操作。但是,打包完的JAR包已经具有软件的几乎全部的功能,因此某些小型工具(如IDE插件等)打包为JAR文件后即可发布。
2. 利用命令行手动打包可执行JAR包
按照以下步骤操作即可得到JAR包。
a. 执行javac命令,编译.java文件得到.class文件
javac命令的标准格式是
javac <options> <source files>
以Hello.java
为例,您可以运行以下命令以得到class文件。
javac Hello.java
这是最基本的javac命令,详细使用方法请查阅javac文档。您可以在终端窗口中输入javac以查看帮助。
b. 新建配置文件
新建文本文件,命名随意,如profile
,内容如下
Manifest-Version: YOUR_VERSION
Main-Class: YOUR_MAIN_CLASS_NAME
将YOUR_VERSION
和YOUR_MAIN_CLASS_NAME
替换为您编写的程序的版本号和主类名称。
c. 归档文件
把编译好的class文件和第2步新建的profile
文件放入指定文件夹,如MySoft
d. 生成JAR
将终端目录切换到MySoft
的上级目录,运行以下命令
jar -cvfm MySoft.jar profile -C MySoft .
jar后面的-m选项会将第2步新建的文件合并到 jar包中的 META-INF/MANIFEST.MF,也就是更新清单配置文件。META-INF文件夹相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序、扩展程序、类加载器和服务。这个文件夹和其中的 MANIFEST.MF文件,在用jar打包时自动生成。执行jar文件的时候,这个jar里是需要具备 META-INF/MANIFEST.MF的,否则java -jar就找不到主类。
-C 后面指定要打包的目录,在这里是MySoft
,目录后面的.
代表目录下所有文件。
至此,JAR文件被成功生成,您可以在文件管理器中看到生成的文件。您可以尝试双击打开生成的JAR,观察软件运行是否正常。
3. 利用IntelliJ IDEA打包可执行JAR包
手动生成JAR包的过程,配置复杂、步骤繁多,而且很容易出现错误,在开发过程中很少使用。IntelliJ IDEA集成了功能强大的Java开发环境,能够提供从项目建立到产品生成的一站式开发流程,是现在Java开发应用最广泛的IDE。利用IntelliJ IDEA可以比较便捷地生成JAR文件,按照以下步骤操作即可生成。
a. 新建工件(Artifacts)
在项目窗口中,点击“文件”(Files)菜单,再点击菜单中的“项目结构”(Project Structure)菜单项,打开“项目结构”窗口。在Windows上,您可以通过“Ctrl+Alt+Shift+S”快捷键打开这一窗口;在Mac上,您可以通过"Command+;"打开这一窗口。
在打开的窗口中点击“工件(Artifacts)”选项,进入工件列表。这一列表初始时是空的,点击左上角的绿色+按钮添加新的工件,在太初的菜单中选择“JAR”,并根据您项目的实际情况,在次级菜单中,选择“空(Empty)”或者"来自具有依赖项的模块(From modules with dependencies…)"。
b. 添加依赖文件
此时您可以看到,工件列表中添加了一个新的JAR工件,点击这一个工件,在“名字(Name)”字段中输入软件的名字, 并指定生成JAR包的保存路径。窗口下侧是“输出结构(Output Layout)”菜单,左边是将添加到JAR的文件或文件夹,右边是排除在JAR之外的文件或文件夹。如果您的软件有依赖项或者独立的数据文件夹,它们将默认展示在分栏的右侧,您可以通过点击或拖动将其添加到左侧的列表中,以在生成的JAR包中保存这些文件。
c. 新建Manifest文件
若您没有生成Manifest文件,窗口中将会显示警告,提示您添加这一配置文件。点击"创建Manifest(Create Manifest)“,选择放置MANIFEST.MF的文件路径,最后点击“确定(OK)”,软件将根据您的设置自动生成Manifest文件。
事实上,在新建工件时,软件就会要求您指定主类名称,进而直接生成Manifest文件。如果新建工件时没有向您提出这一操作,您需要在添加配置文件时指定主类名称及其静态main方法入口,从而生成Manifest文件。
d. 构建工件
您已经完成了软件工件的配置工作,现在IDE已经可以正常地识别并根据您的需要生成JAR包,您只需要点击菜单栏中的“构建(Build)”选项,在弹出的菜单中选择“构建工件(Build Artifacts)”。此时IDE将显示软件的工件列表,您需要选择您刚刚新建的JAR工件,并在弹出的“动作(Action)”菜单中选择“构建(Build)”即可。之后,软件将根据您的需求在您指定的目录中生成软件产品JAR包。
生成完成后,您可以在这一目录中找到软件JAR产品,并可将其复制或移动到其他位置,甚至直接作为最终产品分发。
B. 制作安装包
在已经装有Java虚拟机的电脑上,JAR文件与其他的可执行文件并没有什么区别,可以直接双击运行。但是,大多数的的计算机用户并不是Java开发者,并没有安装Java虚拟化运行环境,所以他们的电脑无法正确运行我们刚刚生成的JAR文件。因此,我们需要向我们刚刚生成的软件产品JAR中添加运行环境依赖,并最终打包成适用于不同操作系统平台的安装包供普通用户安装使用。
在Windows上,安装包一般为.exe
可执行文件,也可以是.iso
映像文件;在Mac上,安装包可以是.pkg
软件包安装助理文件,也可以是.dmg
虚拟磁盘映像文件。我们最终想要生成的软件产品基本就是以上几种文件。
1. 准备工作
a. 整理并检查文件
将打包好的JAR包以及需要的数据文件等一切都准备好,单独放入一个文件夹,特别注意主类和依赖的配置。
- 如果您使用SpringBoot,由于SpringBoot会接管你的主类,您需要使用Spring的插件进行打包操作,将
org.springframework.boot.loader.JarLauncher
作为您项目的主类。 - 如果您使用maven,您需要在
pom.xml
中配置好主类位置。您可以使用copy-dependency插件将依赖包复制到target
文件夹中。
将终端目录切换到这一文件夹,执行以下命令
java -jar MySoft.jar
此时,您应当可以看到您的JAR程序已经正确运行,这说明您已经准备好所有文件,可以进行下一步操作。如果没有,可能说明文件夹中的文件不完整,您需要检查以上步骤是否存在错误。
b. 准备应用图标
无论是Windows还是Mac,您都可以在应用商店或互联网中找到应用程序图标的制作工具,利用这些工具可以轻松地配置并生成应用程序图标。但是,在Mac上,如果您不想使用这些复杂的工具,您也可以尝试下面的方法自己生成图标文件。
- 选取一张图片作为应用程序图标,假设名字为
AppIcon.png
,将其放到上一步骤准备的文件夹中。 - 终端切换到这一文件夹,执行以下命令
mkdir AppIcon.iconset
sips -z 128 128 AppIcon.png --out AppIcon.iconset/icon_128x128.png
iconutil --convert icns AppIcon.iconset
其中
mkdir AppIcon.iconset
命令是指,在当前目录下新建名为AppIcon.iconset
的文件夹;
sips -z 128 128 AppIcon.png --out AppIcon.iconset/icon_128x128.png
命令是指,缩放AppIcon.png
,利用其生成尺寸为128*128
的文件,名为icon_128x128.png
,保存在AppIcon.iconset
中;
iconutil --convert icns AppIcon.iconset
命令是指,将AppIcon.iconset
转换为macOS使用的.icns
图标文件。
以上命令执行完后,您应当可以在文件夹中找到AppIcon.icns
文件,这就是我们制作安装包所使用的图标文件。
根据笔者目前掌握到的信息,Windows系统没有提供与以上命令作用相似的命令行语句,所以在Windows上,您需要下载图标制作软件以完成图标制作步骤。您也可以搜索“在线图标制作工具”,使用网页在线小工具完成这一步骤。
2. 使用javapackager命令完成打包工作
此方法适用于任何系统。
a. 利用生成的JAR,使用-deploy
完成打包工作
终端目录切换到之前步骤准备好的文件夹,执行javapackager命令,格式如下
javapackager -command [-options]
更加具体的一种实现格式可以是
javapackager -deploy -native image -outdir ./outdir -outfile [输出文件名] -appclass [Main类] -srcfiles . -name [应用程序名] -Bicon=[图标路径]
其中-deploy
代表这是部署操作,您还可以使用-createjar
根据其他参数生成JAR档案、-signJar
用提供的证书为 JAR文件签名等,此处保持使用-deploy
即可。
-native image
代表生成自包含的应用程序包,image
代表指定的软件包产品的类型。您可以在其后指定您要生成的软件包的类型,所支持类型的列表包括: installer
, image
, exe
, msi
, dmg
, rpm
和 deb
。如果指定了类型, 则只创建此类型的包。
-outdir ./outdir
代表生成的软件包括产品的输出目录,此处为./outdir
,.
代表当前文件夹。您可以在这一目录下找到生成的软件包产品。
-outfile [输出文件名]
代表生成的软件包的文件名。
-appclass [Main]
代表主类名称,这将作为软件的入口。
-srcfiles .
代表源文件,javapackager将使用这些文件新建软件包。.
代表当前目录下的所有文件。
-name [应用程序名]
代表生成的应用程序的名字,可以与刚才的输出文件名相同,也可以不同。软件打开后,窗口上将显示这一名字。
-Bicon=[图标路径]
代表上一步骤中生成的软件的图标的路径。软件将使用此处提供的图标文件作为图标。在桌面上或应用程序列表中显示这一图标。
您可以在终端中输入javapackager
以获取命令的使用帮助。帮助中给出的一种语句示例是
javapackager -deploy -outdir outdir -outfile outfile -width 34 -height 43
-name AppName -appclass package.ClassName -v -srcdir compiled
代表在由 package.ClassName
类启动且大小为 34*43
的应用程序 AppName
的 outdir
中生成 outfile.jnlp
和对应的 outfile.html
文件。
b. 使用-makeall
一次性完成打包工作
您也可以执行以下语句
javapackager -makeall -appclass MAIN_CLASS_PATH -name SOFTWARE_NAME
此命令执行包含编译在内的所有打包工作: compile, createjar 和 deploy。您甚至不需要生成JAR文件,执行此语句一次即可生成适用于您当前操作系统的软件安装包。
命令执行完毕后,您应当可以在输出文件夹中看到已经制作完成的软件安装包。至此,您已经成功创建普通用户也可以便捷使用的软件安装包,可以将其用于对应平台的大规模软件分发。
3. 使用exe4j生成exe
此方法只适用于Windows,用于生成Windows使用的.exe
可执行文件。
JAR包无法用于大规模分发的原因之一,就在于普通用户的电脑中,一般缺少Java虚拟化运行环境,因此我们在制作软件包时,需要在我们的产品中包括我们开发的软件所需要的Java虚拟化运行环境。exe4j并不会自动完成这一工作,因此使用exe4j前,我们需要在“准备工作”步骤中穿件好的文件夹中添加Java虚拟化环境。简单地操作,就是将我们使用的JDK复制一份出来,放到这一文件夹中。
打开exe4j,配置好打包类型为“Regular Mode”,填写好应用的各种信息,并指定distribution source directionary
为刚刚复制出来的JDK文件夹。
指定Executeable type,一般为"GUIApplication(用户界面应用程序)“,否则选择"Console Application(控制台应用程序)”。勾选icon file,然后选择准备好的图标。您可以按需勾选“Allow only a single running instance of the application(只允许单例运行)“,勾选后,此应用程序只能启动一个,也就是说如果此程序已经在运行,是无法重复启动的,最后填写"Executeable name(应用程序的名称)"。
配置“redirection(重定向)”信息。重定向是指控制台信息的保存位置。您可以选择将标准输出System.out.println()
的内容保存到文件中,还可以选择将异常信息保存到一个日志中,您可以按需配置,也可以跳过。
在32-bit or 64-bit
中选择生成的应用程序的指令宽度。如果您需要生成64位应用,请勾选Generate 64-bit executeable
。事实上,当前大部分处理器和操作系统都是64位的,使用32位程序可能会导致应用程序性能不佳,因此笔者建议您生成64位应用。另外您需要注意的是,应用程序指令宽度应当与JDK的一致。
接下来配置构建路径。点击Java invocation
,如果您只有一个JAR包,选择Archive
;如果JAR包很多,您需要将它们放到一个文件夹里面,选择Directory
,然后选择那个文件夹,最后点击OK
按钮,配置好主类和JVM参数。
最后配置JRE。点击左侧Search sequence
,删除所有默认的目录,然后添加一个新目录,位置填写为.
,代表当前文件夹。
以上步骤完成后,点击Finish
,软件就会自动生成.exe
安装包,内部不仅包含了软件的Java可执行文件,还包含了Java可执行文件运行所需要的Java运行环境。
您可以发现,软件的大小比单独的JAR包至少增加了50MB,增加出来的部分大多是Java运行环境的依赖文件。可以预见,如果所有的Java程序在打包为软件安装包时,都包含有一份从相同源文件复制而来的、完整的Java运行环境的依赖文件,那么在用户的电脑上,这些重复的Java运行环境依赖文件将占用电脑的大量空间。因此,我们可以采用包括依赖分析在内的多种方法,只打包软件产品运行需要的那些依赖文件,尽量减小安装包的体积,避免文件冗余。
4. 使用maven插件JavaPackager批量生成多个平台的安装包
此方法适用于任何平台,且在任意单一平台上单次执行就可以同时得到各个平台的软件包。
JavaPackager是一款maven插件,能够用于批量生成各种平台上的Java程序的安装包,并可以精简JRE,最大限度地避免前述的Java运行环境依赖文件冗余问题。配置完成后,仅需在控制台输入一条语句,或者在IDE中单击“生成”按钮,即可一次性生成Windows、macOS、Linux等平台上的Java应用程序安装包。
执行虽然简单,但执行前的配置是关键。您需要使用maven构建项目,并严格遵循以下步骤,仔细完成配置文件的编写。
a. 添加maven插件配置
在pom.xml
的<plugins>...</plugins>
字段中添加以下语句
<plugin>
<groupId>io.github.fvarrui</groupId>
<artifactId>javapackager</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>package</goal>
</goals>
<configuration>
<!-- mandatory -->
<mainClass>path.to.your.mainClass</mainClass>
<!-- optional -->
<bundleJre>true|false</bundleJre>
<generateInstaller>true|false</generateInstaller>
<administratorRequired>true|false</administratorRequired>
<platform>auto|linux|mac|windows</platform>
<additionalResources>
<additionalResource>file path</additionalResource>
<additionalResource>folder path</additionalResource>
<additionalResource>...</additionalResource>
</additionalResources>
</configuration>
</execution>
</executions>
</plugin>
注意准确配置其中的字段。首先,您需要将path.to.your.mainClass
更改为您的软件产品的主类地址;之后配置<bundleJre>
字段为是否添加JRE文件(Java运行环境依赖),<generateInstaller>
为是否生成软件安装器, <administratorRequired>
为软件运行时是否需要请求管理员权限,<platform>
为目标操作系统平台;最后配置<additionalResources>
字段为软件运行所需要的其他资源。
b. 添加操作系统平台配置
配置<execution>
字段,添加以下配置
<execution>
<id>bundling-for-mac|windows|linux</id>
<phase>package</phase>
<goals>
<goal>package</goal>
</goals>
<configuration>
<platform>mac|windows|linux</platform>
[...]
</configuration>
</execution>
<execution>
字段保存的是执行构建命令后插件需要做的操作,如果您想要生成 macOS和Windows的安装包,您需要针对两个系统分别添加一个<execution>
配置。您需要根据不同操作系统平台的实际情况进行配置,对于Windows,您需要将[...]
换成<createZipball>true|false</createZipball>
,以决定是否使用zip打包;对于macOS和Linux,您需要将[...]
换成<createTarball>true|false</createTarball>
,以决定是否使用tar打包。以上两值默认为false
。
c. 执行打包命令
将终端切换到项目文件夹,输入以下命令
mvn package
等待插件运行完成。您将在终端窗口中看到插件的运行日志,运行结束后还会显示插件的运行状态(成功/失败/警告)。您也可以使用可视化工具完成以上工作,仅需点击maven窗口中的"构建"按钮即可。现在,您可以在目标文件夹中找到您配置的针对所有操作系统的安装包,您可以将这些安装包分别发布到不同的操作系统上。
以上是最基本的配置。您还可以访问JavaPackager的GitHub地址以获取更加全面的使用说明。
总结
Java程序的打包和发布过程较为复杂,一般需要使用命令行或第三方工具完成,入门门槛较高。希望您看完本文后,能够对Java程序的打包发布流程有更加清晰的认识。