关于 JAR 您不知道的 5 件事.docx

上传人:b****7 文档编号:15862379 上传时间:2023-07-08 格式:DOCX 页数:7 大小:18.66KB
下载 相关 举报
关于 JAR 您不知道的 5 件事.docx_第1页
第1页 / 共7页
关于 JAR 您不知道的 5 件事.docx_第2页
第2页 / 共7页
关于 JAR 您不知道的 5 件事.docx_第3页
第3页 / 共7页
关于 JAR 您不知道的 5 件事.docx_第4页
第4页 / 共7页
关于 JAR 您不知道的 5 件事.docx_第5页
第5页 / 共7页
关于 JAR 您不知道的 5 件事.docx_第6页
第6页 / 共7页
关于 JAR 您不知道的 5 件事.docx_第7页
第7页 / 共7页
亲,该文档总共7页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

关于 JAR 您不知道的 5 件事.docx

《关于 JAR 您不知道的 5 件事.docx》由会员分享,可在线阅读,更多相关《关于 JAR 您不知道的 5 件事.docx(7页珍藏版)》请在冰点文库上搜索。

关于 JAR 您不知道的 5 件事.docx

关于JAR您不知道的5件事

关于JAR您不知道的5件事

  对于大多数Java开发人员来说,JAR文件及其“近亲”WAR和EAR都只不过是漫长的Ant或Maven流程的最终结果。

标准步骤是将一个JAR复制到服务器(或者,少数情况下是用户机)中的合适位置,然后忘记它。

  事实上,JAR能做的不止是存储源代码,您应该了解JAR还能做什么,以及如何进行。

在这一期的5件事系列中,将向您展示如何最大限度地利用JavaArchive文件(有时候也可是WAR和EAR),特别是在部署时。

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

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

  把它放在JAR中

  通常,在源代码被编译之后,您需要构建一个JAR文件,使用jar命令行实用工具,或者,更常用的是Antjar任务将Java代码(已经被包分离)收集到一个单独的集合中,过程简洁易懂,我不想在这做过多的说明,稍后将继续说明如何构建JAR。

现在,我只需要存档Hello,这是一个独立控制台实用工具,对于执行打印消息到控制台这个任务十分有用。

如清单1所示:

  清单1.存档控制台实用工具

以下是代码片段:

packagecom.tedneward.jars;

  publicclassHello

  {

  publicstaticvoidmain(String[]args)

  {

  System.out.println("Howdy!

");

  }

  }

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

  1.JAR是可执行的

  .NET和C++这类语言一直是OS友好的,只需要在命令行(helloWorld.exe)引用其名称,或在GUIshell中双击它的图标就可以启动应用程序。

然而在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中,使用Antjar任务的manifest元素来指定清单文件:

  清单3.构建我的入口点!

  现在用户在执行JAR文件时需要做的就是通过java-jaroutapp.jar在命令行上指定其文件名。

就GUIshell来说,双击JAR文件即可。

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

  似乎Hello实用工具已经展开,改变实现的需求已经出现。

Spring或Guice这类依赖项注入(DI)容器可以为我们处理许多细节,但是仍然有点小问题:

修改代码使其含有DI容器的用法可能导致清单4所示的结果,如:

  清单4.Hello、Springworld!

 packagecom.tedneward.jars;

  importorg.springframework.context.*;

  importorg.springframework.context.support.*;

  publicclassHello

  {

  publicstaticvoidmain(String[]args)

  {

  ApplicationContextappContext=

  newFileSystemXmlApplicationContext("./app.xml");

  ISpeakspeaker=(ISpeak)appContext.getBean("speaker");

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

  }

  }

  由于启动程序的-jar选项将覆盖-classpath命令行选项中的所有内容,因此运行这些代码时,Spring必须是在CLASSPATH和环境变量中。

幸运的是,JAR允许在清单文件中出现其他的JAR依赖项声明,这使得无需声明就可以隐式创建CLASSPATH,如清单5所示:

  清单5.Hello、SpringCLASSPATH!

value="./lib/org.springframework.context-3.0.1.RELEASE-A.jar

./lib/org.springframework.core-3.0.1.RELEASE-A.jar

./lib/org.springframework.asm-3.0.1.RELEASE-A.jar

./lib/org.springframework.beans-3.0.1.RELEASE-A.jar

./lib/org.springframework.expression-3.0.1.RELEASE-A.jar

./lib/commons-logging-1.0.4.jar"/>

  注意Class-Path属性包含一个与应用程序所依赖的JAR文件相关的引用。

您可以将它写成一个绝对引用或者完全没有前缀。

这种情况下,我们假设JAR文件同应用程序JAR在同一个目录下。

  不幸的是,value属性和AntClass-Path属性必须出现在同一行,因为JAR清单文件不能处理多个Class-Path属性。

因此,所有这些依赖项在清单文件中必须出现在一行。

当然,这很难看,但为了使java-jaroutapp.jar可用,还是值得的!

  3.JAR可以被隐式引用

  如果有几个不同的命令行实用工具(或其他的应用程序)在使用Spring框架,可能更容易将SpringJAR文件放在公共位置,使所有实用工具能够引用。

这样就避免了文件系统中到处都有JAR副本。

Java运行时JAR的公共位置,众所周知是“扩展目录”,默认位于lib/ext子目录,在JRE的安装位置之下。

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

  4.Java6允许类路径通配符

  为了避免庞大的CLASSPATH环境变量(Java开发人员几年前就应该抛弃的)和/或命令行-classpath参数,Java6引入了类路径通配符的概念。

与其不得不启动参数中明确列出的每个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.随机响应

以下是代码片段:

 packagecom.tedneward.jars;

  importjava.util.*;

  publicclassSpeakEnglish

  implementsISpeak

  {

  Propertiesresponses=newProperties();

  Randomrandom=newRandom();

  publicStringsayHello()

  {

  //Pickaresponseatrandom

  intwhich=random.nextInt(5);

  returnresponses.getProperty("response."+which);

  }

  }

  可以将responses.properties放入JAR文件,这意味着部署JAR文件时至少可以少考虑一个文件。

这只需要在JAR步骤中包含responses.properties文件即可。

  当您在JAR中存储属性之后,您可能想知道如何将它取回。

如果所需要的数据与JAR文件在同一位置,正如前面的例子中提到的那样,不需要费心找出JAR文件的位置,使用JarFile对象就可将其打开。

相反,可以使用类的ClassLoader找到它,像在JAR文件中寻找“资源”那样,使用ClassLoadergetResourceAsStream()方法,如清单7所示:

  清单7.ClassLoader定位资源

以下是代码片段:

 packagecom.tedneward.jars;

  importjava.util.*;

  publicclassSpeakEnglish

  implementsISpeak

  {

  Propertiesresponses=newProperties();

  //...

  publicSpeakEnglish()

  {

  try

  {

  ClassLoadermyCL=SpeakEnglish.class.getClassLoader();

  responses.load(

  myCL.getResourceAsStream(

  "com/tedneward/jars/responses.properties"));

  }

  catch(Exceptionx)

  {

  x.printStackTrace();

  }

  }

  //...

  }

  您可以按照以上步骤寻找任何类型的资源:

配置文件、审计文件、图形文件,等等。

几乎任何文件类型都能被捆绑进JAR中,作为一个InputStream获取(通过ClassLoader),并通过您喜欢的方式使用。

  结束语

  本文涵盖了关于JAR大多数开发人员所不知道的5件最重要的事—至少基于历史,有据可查。

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2