简化Java应用程序的打包和发布
发布Java应用程序时你会感到困难?好在Java提供了一系列打包和发布工具,可以显著的简化发布过程
该文章提供了打包Java code的几种方法,我们将会探讨Java manifest 文件,给出用于管理JAR文件所依赖文件、估计跨平台发布所需的CLasspath的合适方法.我也会解释如何使用manifest包版本特性来确认包的兼容性...
什么是JAR文件?
在开发过程中,我们可以直接使用Java class文件来运行程序,但这并不是一个好方式,好在Java 提供了 JAR(Java Archive)文件来提供发布和运行。
jar 文件实际上是class 文件的ZIP压缩存档,这种格式被广泛使用,因此易与使用,有很多中工具可以操作这种格式的文件。也正是因为这个原因,jar文件本身并不能表达所包含应用程序的标签信息。
Manifest 因此得以出现
为了要提供存档的标签信息,jar 文件指定了一个特定目录来存放标签信息:META-INF 目录,其中我们来关注该目录中的MANIFEST.MF文件,他就是JAR的manifest文件,他包含了JAR文件的内容描述,并在运行时向JVM提供应用程序的信息,大多数JAR文件含有一个默认生成的manifest 文件,执行JAR命令或使用zip工具,都可以产生它
如果是由jar命令产生的 manifest 文件,形如:
Manifest-Version: 1.0
Created-By:1.4.0-beta
(Sun Microsystems Inc.)
这些信息没甚么用,仅仅告诉我们使用的是1.0的manifest文件,第一行定义manifest的格式,第二行说明使用 SUN 的JDK1.4的jar工具生成该文件,如果manifest文件是由其他 (如ant) 创建的,那将会出现 “Created-By: Ant 1.2” 之类的内容,如果你是自己创建manifest文件,你可以加入自己的一些相关信息.
基础格式
manifest 文件的格式 是很简单的,每一行都是 名-值 对应的:属性名开头,接着是 ":" ,然后是属性值,每行最多72个字符,如果需要增加,你可以在下一行续行,续行以空格开头,以空格开头的行都会被视为前一行的续行。
所有在开头的属性都是全局的,你也可以定义特定class 或package的属性,稍后将介绍这种
把manifest文件插入JAR文件
使用 m 选项,把指定文件名的manifest文件 传入,例如
jar cvfm myapplication.jar myapplication.mf -C classdir
如果你使用ant来创建时,在ant 的build.xml 加入如下条目
<target name="jar">
<jar jarfile ="myapplication.jar"
manifest="myapplication.mf">
<fileset dir="classdir"
includes="**/*.class"/>
</jar>
</target>
运行Java程序
现在我们来体验一下manifest文件的作用,如果现在我们有一个Java 应用程序打包在myapplication.jar中, main class为 com.example.myapp.MyAppMain ,那么我们可以用以下的命令来运行
java -classpath myapplication.jar com.example.myapp.MyAppMain
这显然太麻烦了,现在我们来创建自己的manifest文件,如下:
Manifest-Version: 1.0
Created-By: JDJ example
Main-Class: com.example.myapp.MyAppMain
这样我们就可以使用如下的命令来运行程序了:(明显简单多了,也不会造成无谓的拼写错误)
java -jar myapplication.jar
管理JAR的依赖资源
很少Java应用会仅仅只有一个jar文件,一般还需要 其他类库。比如我的应用程序用到了Sun 的 Javamail classes ,在classpath中我需要包含activation.jar 和 mail.jar,这样在运行程序时,相比上面的例子,我们要增加一些:
java -classpath mail.jar:activation.jar -jar myapplication.jar
在不同的操作系统中,jar包间的分隔符也不一样,在UNIX用“:”,在window中使用 “;”,这样也不方便
同样,我们改写我们的manifest文件,如下
Manifest-Version: 1.0
Created-By: JDJ example
Main-Class: com.example.myapp.MyAppMain
Class-Path: mail.jar activation.jar
(加入了Class-Path: mail.jar activation.jar,用空格分隔两个jar包)
这样我们仍然可以使用和上例中相同的命令来执行该程序:
java -jar myapplication.jar
Class-Path属性中包含了用空格分隔的jar文件,在这些jar文件名中要对特定的字符使用逃逸符,比如空格,要表示成"%20",在路径的表示中,都采用“/”来分隔目录,无论是在什么操作系统中,(即使在window中),而且这里用的是相对路径(相对于本身的JAR文件):
Manifest-Version: 1.0
Created-By: JDJ example
Main-Class: com.example.myapp.MyAppMain
Class-Path: ext/mail.jar ext/activation.jar
Multiple Main Classes(多主类)
还有一种Multiple Main Classes情况,如果你的应用程序可能有命令行版本 和GUI版本,或者一些不同的应用却共享很多相同的代码,这时你可能有多个Main Class,我们建议你采取这样的策略:把共享的类打成lib包,然后把不同的应用打成不同的包,分别标志主类:如下
Manifest for myapplicationlib.jar:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: mail.jar activation.jar
Manifest for myappconsole.jar:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: myapplicationlib.jar
Main-Class: com.example.myapp.MyAppMain
Manifest for myappadmin.jar:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: myapplicationlib.jar
Main-Class: com.example.myapp.MyAdminTool
在myappconsole.jar 和 myappadmin.jar的manifest文件中分别注明各自的 Main Class
Package Versioning
完成发布后,如果使用者想了解 ,哪些代码是谁的?目前是什么版本?使用什么版本的类库?解决的方法很多 ,manifest提供了一个较好的方法,你可以在manifest文件中描述每一个包的信息。
Java 秉承了实现说明与描述分离的原则,package 的描述 定义了package 是什么,实现说明 定义了谁提供了描述的实现,描述和实现包含 名、版本号和提供者。要得到这些信息,可以查看JVM的系统属性(使用 java.lang.System.getProperty() )
在manifest文件中,我可以为每个package定义描述和实现版本,声明名字,并加入描述属性和实现属性,这些属性是
Specification-Title
Specification-Version
Specification-Vendor
Implementation-Title
Implementation-Version
Implementation-Vendor
当要提供一个类库或编程接口时,描述信息显得是很重要,见以下范例:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: mail.jar activation.jar
Name: com/example/myapp/
Specification-Title: MyApp
Specification-Version: 2.4
Specification-Vendor: example.com
Implementation-Title: com.example.myapp
Implementation-Version: 2002-03-05-A
Implementation-Vendor: example.com
Package Version 查询
在manifest文件中加入package描述后,就可以使用Java提供的java.lang.Package class进行Package 的信息查询,这里列举3个最基本的获取package object的方法
1.Package.getPackages():返回系统中所有定义的package列表
2.Package.getPackage(String packagename):按名返回package
3.Class.getPackage():返回给定class所在的package
使用者这方法就可以动态的获取package信息.
需要注意的是如果给定的package中没有class被加载,则也无法获得package 对象
Manifest 技巧
总是以Manifest-Version属性开头
每行最长72个字符,如果超过的化,采用续行
确认每行都以回车结束,否则改行将会被忽略
如果Class-Path 中的存在路径,使用"/"分隔目录,与平台无关
使用空行分隔主属性和package属性
使用"/"而不是"."来分隔package 和class ,比如 com/example/myapp/
class 要以.class结尾,package 要以 / 结尾
mag.javadigest.net 编译 英文原文
翻译 yife
引用:http://www.jdon.com/jivejdon/forum/messageList.shtml?thread=15361&message=6994399
分享到:
相关推荐
《jQuery Manifest 插件详解与应用实践》 ...同时,随着Web技术的不断发展,如Service Worker等新型离线解决方案的出现,jQuery Manifest插件也为开发者提供了过渡和学习的桥梁,帮助他们更好地适应未来的技术趋势。
学习使用MANIFEST.MF文件来定义bundle的元数据,包括导出和导入的包。 4. **服务编程**:学习如何在OSGi环境中发布和查找服务,使用服务注册表进行服务交互。理解服务的生命周期和服务事件。 5. **配置管理**:...
steam-appmanifest, 在 ~/.steam/steam/SteamApps 中,生成 appmanifest_APPID.acf 文件 Steam AppManifest生成器这是一个简短的python 脚本,可以让 Steam 下载到下载非Linux应用程序中。注:Steam 不会运行没有...
【标题】:“Firefox OS开发的学习_02_app_manifest”这一主题主要聚焦于Firefox操作系统(Firefox OS)中的应用清单(App Manifest)开发。在Firefox OS应用生态中,App Manifest是一个至关重要的部分,它提供了...
6. **教程与参考**:提供`manifest`文件相关规范和最佳实践的链接,方便学习和查阅。 在`manifest-explorer-master`这个压缩包中,很可能包含了源代码、文档、示例文件和安装指南等内容。源代码部分可能用...
同时,这也是一种学习其他应用设计和实现策略的方式。 在实际操作中,除了`AXMLPrinter2.jar`,还有其他的工具,如`Apktool`、`Jadx`等,它们提供了更全面的APK反编译和分析功能,不仅可以解析`AndroidManifest.xml...
本文将深入探讨"apk反编译工具反编译manifest"这一主题,以及如何使用JD-GUI进行APK的反编译。 首先,我们需要理解`AndroidManifest.xml`文件,这是APK的核心组件,它包含了应用的元数据,如应用名称、版本信息、所...
总之,通过学习和应用这个"Visual C++制作XP风格的窗体界面_manifest.rar"中的内容,我们可以了解到如何在VC++中创建具有XP风格的窗体界面,以及如何处理相关的兼容性和用户体验问题。这个过程涉及到Manifest文件的...
标题“manifest mtiso”和描述“it is a c# sample of voip phone”指向了一个与VoIP(Voice over Internet Protocol)相关的C#示例程序。VoIP是一种通过IP网络传输语音的技术,它允许用户通过互联网打电话,而不是...
总结,通过"Maven原型创建一个简单的Bukkit插件",我们可以学习到如何利用现代开发工具提升效率,以及Bukkit插件开发的基本流程。结合"manifest-merger-22.1.1.zip",我们可以思考在不同场景下解决依赖冲突的策略,...
2. **示例**:可能有使用该库的示例代码,帮助开发者了解如何在自己的项目中引入和使用file-manifest。 3. **文档**:详细说明了库的用法、API接口和配置选项,便于学习和参考。 4. **测试**:可能包含单元测试或...
manifest.json 是一个重要的配置文件,尤其在HBuilderX中,它是用于构建5+移动App的关键元素。...随着对HBuilderX和HTML5+ API的深入学习,你会更加熟练地掌握manifest.json的使用,从而创建出更加优秀的移动应用。
【标题解析】 "open_video_tracking.rar" 是一个压缩包...通过这个项目,初学者不仅可以学习到如何使用OpenCV来处理视频,还能了解到一个实际项目的基本结构和开发流程,对提升计算机视觉领域的实践能力非常有帮助。
标题中的“Python库 | aws_manifest-0.1.0-py3.7.egg”表明这是一个基于Python的库,名为`aws_manifest`,版本为...为了深入了解和使用这个库,用户应该查阅官方文档,学习其API接口、示例代码以及如何安装和配置。
EXTJS的学习资料可能包括教程、API文档、示例代码、视频课程等,用于帮助开发者学习如何使用EXTJS来构建现代Web应用。 然而,压缩包中的文件列表与EXTJS学习资料没有直接关联,反而暗示可能与修复或安装使用VC++ ...
学习清单V3 最后,该是对Manifest V3认真的时候了: 到目前为止的节目 :check_mark_button: 如果您像我,那么您a)不喜欢煤尘的味道,因此b)甚至从未尝试过Chrome Canary。 :warning: 好吧...废话UI栏中有一...
这个压缩包可能是为了帮助用户理解和学习如何配置和使用`apiary.manifest`,以便更好地在Apiary上管理和展示他们的API项目。 **API 设计与文档化** 在API设计过程中,APIBlueprint允许开发者定义HTTP请求、响应...
通过深入研究这些文件,开发者可以学习如何在自己的应用中实施凭证清单,以遵循Web身份验证的最佳实践。 结合HTML标准,`credential-manifest`能够更好地融入Web开发的现有框架。例如,通过HTML的`<link>`标签,...
`ssd_mobilenetv1_model-weights_manifest.json`是该模型的权重配置文件,用于加载模型的权重数据。 2. **人脸关键点检测(Face Landmarks Detection)**:`face_landmark_68_model`和`face_landmark_68_tiny_model...
同时,对于想要学习游戏开发或对Minecraft有深入兴趣的用户,这个项目也是一个宝贵的资源,可以从中学习到如何与Mojang的API交互,以及如何构建和维护一个复杂的跨平台应用程序。 总的来说,mcpelauncher-manifest...