对于大多数 Java 开发人员来说,JAR 文件及其 “近亲” WAR 和 EAR 都只不过是漫长的 Ant 或 Maven 流程的最终结果。标准步骤是将一个 JAR 复制到服务器(或者,少数情况下是用户机)中的合适位置,然后忘记它。

事实上,JAR 能做的不止是存储源代码,您应该了解 JAR 还能做什么,以及如何进行。在这一期的 5 件事 系列中,将向您展示如何最大限度地利用 Java Archive 文件(有时候也可是 WAR 和 EAR),特别是在部署时。

由于有很多 Java 开发人员使用 Spring(因为 Spring 框架给传统的 JAR 使用带来一些特有的挑战),这里有几个具体技巧用于在 Spring 应用程序中处理 JAR 。

我将以一个标准 Java Archive 文件产生过程的简单示例开始,这将作为以下技巧的基础。

把它放在 JAR 中

通常,在源代码被编译之后,您需要构建一个 JAR 文件,使用 jar 命令行实用工具,或者,更常用的是 Ant jar 任务将 Java 代码(已经被包分离)收集到一个单独的集合中,过程简洁易懂,我不想在这做过多的说明,稍后将继续说明如何构建 JAR。现在,我只需要存档 Hello,这是一个独立控制台实用工具,对于执行打印消息到控制台这个任务十分有用。如例 1 所示:

例 1. 存档控制台实用工具

package com.tedneward.jars;

public class Hello

{

public static void main(String[] args)

{

System.out.println(“Howdy!”);

}

}

Hello 实用工具内容并不多,但是对于研究 JAR 文件却是一个很有用的 “脚手架”,我们先从执行此代码开始。

回页首

1. JAR 是可执行的

.NET 和 C++ 这类语言一直是 OS 友好的,只需要在命令行(helloWorld.exe)引用其名称,或在 GUI shell 中双击它的图标就可以启动应用程序。然而在 Java 编程中,启动器程序 — java — 将 JVM 引导入进程中,我们需要传递一个命令行参数(com.tedneward.Hello)指定想要启动的 main() 方法的类。

这些附加步骤使使用 Java 创建界面友好的应用程序更加困难。不仅终端用户需要在命令行输入所有参数(终端用户宁愿避开),而且极有可能使他或她操作失误以及返回一个难以理解的错误。

这个解决方案使 JAR 文件 “可执行” ,以致 Java 启动程序在执行 JAR 文件时,自动识别哪个类将要启动。我们所要做的是,将一个入口引入 JAR 文件例文件(MANIFEST.MF 在 JAR 的 META-INF 子目录下),像这样:

例 2. 展示入口点!

Main-Class: com.tedneward.jars.Hello

这个例文件只是一个名值对。因为有时候例文件很难处理回车和空格,然而在构建 JAR 时,使用 Ant 来生成例文件是很容易的。在例 3 中,使用 Ant jar 任务的 manifest 元素来指定例文件:

例 3. 构建我的入口点!

现在用户在执行 JAR 文件时需要做的就是通过 java -jar outapp.jar 在命令行上指定其文件名。就 GUI shell 来说,双击 JAR 文件即可。

回页首

2. JAR 可以包括依赖关系信息

似乎 Hello 实用工具已经展开,改变实现的需求已经出现。Spring 或 Guice 这类依赖项注入(DI)容器可以为我们处理许多细节,但是仍然有点小问题:修改代码使其含有 DI 容器的用法可能导致例 4 所示的结果,如:

例 4. Hello、Spring world!

package com.tedneward.jars;

import org.springframework.context.*;

import org.springframework.context.support.*;

public class Hello

{

public static void main(String[] args)

{

ApplicationContext appContext =

new FileSystemXmlApplicationContext(“./app.xml”);

ISpeak speaker = (ISpeak) appContext.getBean(“speaker”);

System.out.println(speaker.sayHello());

}

}

关于 Spring 的更多信息

这个技巧将帮助您熟悉依赖项注入和 Spring 框架。

由于启动程序的 -jar 选项将覆盖 -classpath 命令行选项中的所有内容,因此运行这些代码时,Spring 必须是在 CLASSPATH 和 环境变量中。幸运的是,JAR 允许在例文件中出现其他的 JAR 依赖项声明,这使得无需声明就可以隐式创建 CLASSPATH,如例 5 所示:

例 5. Hello、Spring CLASSPATH!

注意 Class-Path 属性包含一个与应用程序所依赖的 JAR 文件相关的引用。您可以将它写成一个绝对引用或者完全没有前缀。这种情况下,我们假设 JAR 文件同应用程序 JAR 在同一个目录下。

不幸的是,value 属性和 Ant Class-Path 属性必须出现在同一行,因为 JAR 例文件不能处理多个 Class-Path 属性。因此,所有这些依赖项在例文件中必须出现在一行。当然,这很难看,但为了使 java -jar outapp.jar 可用,还是值得的!

回页首

3. JAR 可以被隐式引用

如果有几个不同的命令行实用工具(或其他的应用程序)在使用 Spring 框架,可能更容易将 Spring JAR 文件放在公共位置,使所有实用工具能够引用。这样就避免了文件系统中到处都有 JAR 副本。Java 运行时 JAR 的公共位置,众所周知是 “扩展目录” ,默认位于 lib/ext 子目录,在 JRE 的安装位置之下。

JRE 是一个可定制的位置,但是在一个给定的 Java 环境中很少定制,以至于可以完全假设 lib/ext 是存储 JAR 的一个安全地方,以及它们将隐式地用于 Java 环境的 CLASSPATH 上。

回页首

4. Java 6 允许类路径通配符

为了避免庞大的 CLASSPATH 环境变量(Java 开发人员几年前就应该抛弃的)和/或命令行 -classpath 参数,Java 6 引入了类路径通配符 的概念。与其不得不启动参数中明确列出的每个 JAR 文件,还不如自己指定 lib/*,让所有 JAR 文件列在该目录下(不递归),在类路径中。

不幸的是,类路径通配符不适用于之前提到的 Class-Path 属性例入口。但是这使得它更容易启动 Java 应用程序(包括服务器)开发人员任务,例如 code-gen 工具或分析工具。

回页首

5. JAR 有的不只是代码

Spring,就像许多 Java 生态系统一样,依赖于一个描述构建环境的配置文件,前面提到过,Spring 依赖于一个 app.xml 文件,此文件同 JAR 文件位于同一目录 — 但是开发人员在复制 JAR 文件的同时忘记复制配置文件,这太常见了!

一些配置文件可用 sysadmin 进行编辑,但是其中很大一部分(例如 Hibernate 映射)都位于 sysadmin 域之外,这将导致部署漏洞。一个合理的解决方案是将配置文件和代码封装在一起 — 这是可行的,因为 JAR 从根本上来说就是一个 “乔装的” ZIP 文件。 当构建一个 JAR 时,只需要在 Ant 任务或 jar 命令行包括一个配置文件即可。

JAR 也可以包含其他类型的文件,不仅仅是配置文件。例如,如果我的 SpeakEnglish 部件要访问一个属性文件,我可以进行如下设置,如例 6 所示:

例 6. 随机响应

package com.tedneward.jars;

import java.util.*;

public class SpeakEnglish

implements ISpeak

{

Properties responses = new Properties();

Random random = new Random();

public String sayHello()

{

// Pick a response at random

int which = random.nextInt(5);

return responses.getProperty(“response.” + which);

}

}

可以将 responses.properties 放入 JAR 文件,这意味着部署 JAR 文件时至少可以少考虑一个文件。这只需要在 JAR 步骤中包含 responses.properties 文件即可。

当您在 JAR 中存储属性之后,您可能想知道如何将它取回。如果所需要的数据与 JAR 文件在同一位置,正如前面的例子中提到的那样,不需要费心找出 JAR 文件的位置,使用 JarFile 对象就可将其打开。相反,可以使用类的 ClassLoader 找到它,像在 JAR 文件中寻找 “资源” 那样,使用 ClassLoader getResourceAsStream() 方法,如例 7 所示:

例 7. ClassLoader 定位资源

package com.tedneward.jars;

import java.util.*;

public class SpeakEnglish

implements ISpeak

{

Properties responses = new Properties();

// …

public SpeakEnglish()

{

try

{

ClassLoader myCL = SpeakEnglish.class.getClassLoader();

responses.load(

myCL.getResourceAsStream(

“com/tedneward/jars/responses.properties”));

}

catch (Exception x)

{

x.printStackTrace();

}

}

// …

}

您可以按照以上步骤寻找任何类型的资源:配置文件、审计文件、图形文件,等等。几乎任何文件类型都能被捆绑进 JAR 中,作为一个 InputStream 获取(通过 ClassLoader),并通过您喜欢的方式使用。

注意,所有的 JAR 相关技巧对于 WAR 同样可用,一些技巧(特别是 Class-Path 和 Main-Class 属性)对于 WAR 来说不是那么出色,因为 servlet 环境需要全部目录,并且要有一个预先确定的入口点,但是,总体上来看这些技巧可以使我们摆脱 “好的,开始在该目录下复制……” 的模式,这也使得他们部署 Java 应用程序更为简单。

jar包 java_深入理解JAR包相关推荐

  1. jar包和war包区别及理解

    在开发阶段不适合使用war包,因为在开发阶段,经常需要添加或删除Web应用程序的内容,更新 Servlet类文件,而每一次改动后,重新建立war包将是一件浪费时间的事情.在产品发布阶段,使用war文件 ...

  2. exe4j将jar包打成exe(添加jar、jdk、dll)

    最近用Java写了一个小工具,想将它达成exe执行文件,到时候直接放某个目录下,一执行就能跑啦. 用到的工具: 1.写好的项目:可以是java项目,也可以是java web项目 2.能够打jar的工具 ...

  3. Java代码安装maven jar,maven添加第三方的jar包

    为项目需求用到pinyin4j 在maven仓库中没有找到对应的jar包就从网上下载了一个 然后手动导入到项目 1.下载pinyin4j-2.5.0.jar 2.放在磁盘路径下 比如D:\pinyin ...

  4. 运行jar应用程序引用其他jar包的四种方法

    http://longdick.iteye.com/blog/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar ...

  5. java打jar包,引用其他.jar文件

    大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar包的程序入口. 具体的方法是修改jar包内目录META-INF下的MANIF ...

  6. jar打包 剔除第三方依赖以及它的依赖_maven打包成第三方jar包且把pom依赖包打入进来的方法...

    添加此PLUGIN到项目的POM.XML中 maven-assembly-plugin com.allen.capturewebdata.Main jar-with-dependencies 如果出现 ...

  7. Eclipse安装低版本4.3并安装FatJar打包插件来打包引用第三方jar包的项目成jar包

    场景 Eclipse中打包引用了第三方jar包的Java Application项目,除了添加MANIFESE.MF文件,还可以使用 Fat Jar插件打成jar包. 但是Eclipse的版本在4.3 ...

  8. axis2 jar包冲突_一个jar包冲突引起的StackOverflowError

    项目运行中错误信息:java.lang.IllegalStateException: Unable to complete the scan for annotations for web appli ...

  9. Eclipse打JAR包引用的第三方JAR包找不到 问题解决

    在做项目过程中,使用Eclipse打成JAR包,使用 Export-->Java-->JAR file ,我的jar包里面还引用了第三方的jar包:比如 log4j, 我也碰到了这样的问题 ...

  10. jar包打补丁 jar -uf_maven项目引入本地jar包的方法

    maven项目引入本地jar包的方法 标签:maven 当maven项目中从中央仓库中找到不到某些Jar包,或者想把自己开发的Jar文件引入到项目中使用.可以把Jar包上传maven中央仓库或自建的私 ...

最新文章

  1. 【实践】WCF 传输安全 1 前期准备之证书制作
  2. 【 FPGA 】MATLAB 生成 FIR 滤波器的操作步骤(包括生成Verilog HDL代码以及仿真过程)
  3. Linux 高级I/O之poll函数及简单服务器客户端编程
  4. [BUUCTF-pwn]——test_your_nc
  5. Java学习笔记一和前言
  6. ERP failure: Error when opening an RFC connection
  7. 机器学习算法总结--EM算法
  8. Google 誓要干掉 URL!
  9. 正经程序员是怎么完美度过元旦假期的?
  10. 云平台圈地须群攻莫单打
  11. 如何使用NFC读写器读卡器ACR122U-A9|ACR1251U-M1|ACR1252U读写NDEF格式的智能海报|网址|文本等数据的方法与步骤
  12. 21世纪十大营销法则
  13. python星空代码_Python中的唯美星空代码详解!
  14. debian adsl上网
  15. IJCAI2021 Person Re-identification相关论文集合推荐
  16. 辣椒疫霉RXLR效应子抑制植物免疫
  17. Project Management
  18. 在美国读书的体会 [转]
  19. python agg函数_个人对Pandas中agg、apply和transform函数的理解
  20. 王者荣耀 是什么语言编写的

热门文章

  1. hadoop 开发环境设置以及可运行jar包生成
  2. poj 3074 Sudoku
  3. NinePatchChunk.java分析
  4. 快速开发框架V0.001(免费、100%开源)
  5. 查看系统信息msinfo32工具的使用
  6. 一份招聘需求的分析 (转载)
  7. Kubernetes v1.14.0 之 kube_scheduler 部署
  8. HDU-2063-过山车(最大匹配)
  9. 春节咋过?韩上班族平均休4天 计划花费2756元人民币
  10. linux系统学习第二天