`

在可移动应用中工具类Jar文件打包机制探索

阅读更多
Many J2EE applications use utility classes or libraries that provide some extra functionality not supported by the application code or the J2EE platform APIs. Often these libraries are jarred up so they can be used by multiple applications. These jarred up libraries can be home-grown or obtained from a third party. An application using a library that is a provided to your application code is a common and valid use case for apps and is supported by J2EE.

If you are already familiar with the mechanisms in J2EE for portable packaging of library jar files, feel free to skip to the scenarios section where the mechanisms are applied to various application packaging scenarios.

Here are some common example use case scenarios:
1.    An application that uses Struts and its APIs to provide an MVC framework. The application code then depends on these Struts classes as well as the standard APIs provided by the J2EE application server. 
2.    An application uses JSTL so it has a jstl.jar files to provide some tags which are used by the application's JSP pages. 
3.    An application uses a logging utility which may be a third-party library jar or home-grown library jar. This logging utility is used by many different applications so is a separate jar file in order to be re-used.
Once you have decided to use one of these libraries, deciding how to package these extra libraries along with the application code is an important design decision. It can affect the portability of your application. It can affect the size of your war and ear files. It can affect the maintenance of the application and version control as libraries and application servers are updated. So the choice of how to handle these libraries has some important impacts.

Solution
For portable applications there are several mechanisms in J2EE to support using optional packages such as a jarred up library or utility. These mechanisms are reviewed briefly in the table below. For each of these mechanisms, you need to determine where to place the library jar file and how the referencing application jar(ear, war, etc) files can indicate where the library jar can be found(through an explicit reference or placed in well-known location such as WEB-INF/lib or J2SE lib/ext).

Overview of Mechanisms to support optional packages
There are some solutions that are application-server specific for packaging library jar files. For example, placing a library jar file in an application server's classpath so that applications can use the APIs that are in that jar file. Or some application servers have container specific locations where you can just drop jar files to be shared by applications and modules. But these mechanisms are application specific and are less favorable to using the portable mechanisms provided by J2EE. Lets take a brief look at the portable mechanisms for using optional packages such as library jar files. Some of these mechanisms are J2EE specific and some leverage the J2SE extension architecture mechanisms for handling optional packages. For a detailed description of these mechanisms, refer to the References section at the end of this document.

Note that some application servers allow for mechanisms beyond these portbale mechanisms. So often, just dropping a jar file in a certain location will allow an application to deploy and run even. But is is best to use the portable mechanisms described below.
Mechanism 1: The WEB-INF/lib directory
Just place a library jar file such as struts.jar into WEB-INF/lib and a web application or web module can use the struts APIs. This can only be used by web modules(war files). With this mechanism the library jar file is included as part of the war file. The WEB-INF/lib is a well-known location to find libraries and is supported by J2EE. Note that the library jar file is just scoped to the web module where it is is bundled inside the WEB-INF/lib directory and can not be shared by other modules or applications. This mechanism can not be used by EJB modules.
Mechanism 2: Bundled optional classes 
Use the Class-Path attribute and manifest file to reference a library jar file(s) that is included in the ear file. With this mechanism the library jar file is included as part of the referencing jar file(ear file), sometimes it is said the library is bundled. Since ear files and war files etc are JAR files they can leverage the JAR mechanisms to reference dependent jar files. A manifest file META-INF/MANIFEST.MF is included in the referencing jar file and in the manifest file the Class-Path attribute is included along with the module referencing the library jar being used. More than one library can be listed in the Class-Path. Class-Path is one of the Jar-file manifest attributes.

The J2EE 1.4 specification mentions that top-level JAR files, such as .ear files, should not contain Class-Path references since it would reference files external to the top-level JAR. With this mechanism, the library jar file should be bundled as part of the ear/war jar file and should not be external.

Here is an example for an ear file containing a web module that uses Struts:
application.ear: 
  META-INF/application.xml 
  struts.jar 
  webapp.war 
              META-INF/MANIFEST.MF:
                  Manifest-Version: 1.0
                  Class-Path: struts.jar 
               WEB-INF/web.xml 
Mechanism 3: Installed packages
Use the Extension-List attribute and manifest file to reference a library jar file(s) that is not bundled in the ear file but is  installed in some well-known location, usually the lib/ext of J2SE. With this mechanism the library jar file is *not* included as part of the ear file. The library jar file(s) referenced is external to the ear file and instead stored in install directory, where this external location is referenced using the Extension-List. In this case these are often called installed libraries. In the application ear file, the manifest file is used and the Extension-List attribute is used  to express its dependency on a library jar file. More than one library can be listed in the Extension-List. The applications will not deploy if the application server can not find the library and resolve the dependency. Extension-List is one of the Jar-file manifest attributes. This attribute indicates the optional packages that are needed.
Note, when using this installed packages mechanism, the library jar file is available to all applications.

Here is an example(from J2EE 1.4 spec) where util.jar is placed in the install directory lib\ext and util.jar is used by app1.ear application:
app1.ear:
      META-INF/application.xml
      ejb1.jar:
            META-INF/MANIFEST.MF:
                    Extension-List: util
                    util-Extension-Name: com/example/util
                    util-Extension-Specification-Version: 1.4
             META-INF/ejb-jar.xml

util.jar:
      META-INF/MANIFEST.MF:
               Extension-Name: com/example/util
               Specification-Title: example.com’s util package
               Specification-Version: 1.4
               Specification-Vendor: example.com
               Implementation-Version: build96
Brief description of  the J2SE 1.4 extensions for optional packages
The J2EE 1.4 mechanisms for portably packaging library jar files leverage the J2SE mechanisms for allowing applications to use jarred up libraries. So it might be useful to briefly review some of these concepts. Note that optional packages is the new term for what used to be known as standard extensions or just extensions.

Here are two ways that J2SE allows optional packages(these are paraphrased from the Optional Packages Overview document):
1.    Installed optional packages are JAR files located in the directory lib/ext [in the Java 2 Runtime Environment] or jre/lib/ext [in the Java 2 SDK]. The jar file should have a manifest file describing itself. 
2.    Download optional packages, also called bundled optional packages. A bundled/download optional package is a JAR files that is specified in the Class-Path header field in the manifest of another JAR files. Classes in download optional packages may be used by classes in the referencing JAR file. Unlike the case of installed optional packages, the location of the JAR files that serve as bundled/download optional packages is irrelevant. A download optional package is an optional package because it is specified as the value of the Class-Path header in another JAR file's manifest, not because it has any particular location.
Precedence Order
What if an application ear file uses more than one mechanism to reference a library in its packaging? Or what if multiple versions (or multiple copies of the same version) of a library jar file are present? Which instance of the jar file would be used at runtime by the application? Note the order of precedence in J2EE and J2SE may be different, and the J2EE specification applies to applications deployed on application servers. The J2EE specification recommends a precedence order for resolving the finding of an optional package. Generally an application server will look for a class in a library jar file in the order of precedence: first the WEB-INF/lib mechanism, then the bundled optional package mechanism, and then the installed optional package mechanism. If a class can not be found then the application should not be deployed. Also, note that application servers often will not let a library jar file replace a platform API, so for example an inclusion of your own servlet.jar file using one of these mechanisms will often be ignored. This is a safety precaution to avoid having mistakes alter the container behavior for standard platform APIs.

Scenarios
Now that we know the mechanisms for portably packaging an optional package jarred up as a a library JAR file, lets look at how they can be applied to some common scenarios for J2EE applications. These use cases are based on the questions and scenarios folks have been frequently asking about.  
Scenario:The application is a stand-alone war file that uses a library file(s).
When an application consists of a war file and does not intend to create an ear file. Note, in J2EE 1.4, a stand-alone module such as a war file is considered a valid J2EE application and no ear file wrapper is required.

In this case, you can use the WEB-INF/lib mechanism. Just include the struts.jar in the WEB-INF/lib directory of the war file, no other steps are required. The library jar file is packaged as part of the war file. A web application can add more library jar files used by an application in this manner. So if two or more libraries are used, then just include all the library jar files.

The bundled optional packages mechanism  would *not* work since the war file in this case is a top-level jar(a stand-alone war or .ear file) and top-level  jars should not have Class-Path attributes. It would imply something external to the top level jar instead of bundled inside it. 
 
The installed optional packages mechanism would work. For example, a library jar file such as struts.jar could be placed in the extensions directory. The application would need to include a manifest file and  indicate that it needs one or more optional packages using the Extension-List attributes. 
Scenario: The application is an ear file containing just one war file that uses a library jar file(s)
Many applications package everything into an ear file. Even for a simple application consisting of one war module, these can be packaged up into an ear file. In this scenario, the web module uses some library APIs so is dependent on the library jar file. The web module may use more than one library and have more than one library dependency.

For this case, you can use all three of the mechanisms. 
Scenario: The application is an ear file containing more than one web module(war files) and these wars each use library jar files
In this case, an ear file has multiple wars that use libraries. You might have war files that use different sets of libraries or  you might have wars that both use the same library.

You can use all 3 mechanisms. 
1.    (mechanism 1)For the WEB-INF/lib mechanism, each web module includes the library jar files it uses in the WEB-INF/lib of its war file. If there is a common library used by more than one war file then the common library will have multiple copies of its jar file, one for each war file using it. Each war file has its own copy, so in this case the other mechanisms might be preferred.
2.    (mechanism 2)For the bundled optional packages mechanism, each module has a manifest file that uses the Class-Path attribute to list all the library jar files that it is dependent on. The library jar file is placed within the ear file. You can have one copy of the library jar and all the web modules that use it can reference that library jar with the Class-Path attribute. 
3.    (mechanism 3)For the installed optional packages mechanism, each module uses the Extension-List attribute and manifest file to express all the libraries it is dependent on. In this case, the ear file does not contain the library jar file, instead the ear file just uses the manifest file to reference the installed extra libraries it uses.
Scenario: The application is an ear file containing  more than one web module(war files) and these web modules want to "share" the same library jar file and not have duplicate copies of the library.
Just want to cover this sharing case separately since it is asked about a lot. An example is an ear file with two war files both using struts and you want them to share the struts.jar instead of having duplicate copies.

You can use the bundled optional packages mechanism or the installed packages mechanism in this scenario. You can *not* use the WEB-INF/lib mechanism for sharing since in this mechanism each web module has its own copy of the library jar file.

For the bundled optional packages mechanism just have each web module use the manifest file and Class-Path attribute to point to the same location for the jar file bundled within the ear file. So this way there is just one copy of the library, such as struts.jar, that is included within the ear file. Otherwise each web module would have two copies of the library jar file and would not be sharing.

For the installed optional packages mechanism, just have each web module use a manifest file and Extension-List attribute to point to the same location of the library installed in the extensions directory, which is not included in the ear file. This way each application is sharing the same library jar file.
Scenario: Multiple applications(different ear files and/or different stand-alone war files ) want to "share" the same library jar file.
In this case you want multiple applications to use the same library and you dont want to include duplicate copies of the library jar file in each application. For example, multiple applications may need to use the same version of the JSTL tag libraries. This case covers applications that are deployed as ear files or applications that are deployed as stand-alone war files.

You can use the installed optional packages mechanism for this. Just put one copy of the library such as struts.jar in the extension directory location and in each application that uses struts APIs, use the manifest file and Extension-List attribute to express this dependency.
Scenario:For application ear files which have EJB module(s) and may or may not have a web layer
Applications can have EJBs that use some library jar files. Some ear files have EJB modules, web modules, etc. Some applications use EJBs but dont have a web tier, for example, a workflow engine designed using JMS and EJBs which has no presentation layer- a headless application. Both of these cases are the same for using and packaging the libraries used by the EJBs.  

For this case you can use the  the bundled optional packages mechanism and the installed optional packages mechanism. 
Scenario: For developers of libraries intended to be used and packaged with applications. 
All the other examples were use cases of an application using a library for a portable application. What if you are a developer of a library such as struts or JSTL or JSF and you want your library to be portable on J2EE 1.4? 
Especially, what if the library you are making has dependencies on some third-party code? For example, JSTL uses a specific version of xalan.jar?

What is the proper way to jar up these libraries so they can be used by a J2EE application?
According to J2EE spec(section 8.2 and 8.4), if you want to make a jar that is used as an optional package then it should be packaged as a .jar file according to the Extension Mechanism Architecture. So the jar file should have manifest file that declares its dependencies.
分享到:
评论

相关推荐

    jarjar-方便Java打包工具,自定义修改jar包包名

    Java开发过程中,打包工具起着至关重要的作用,它们帮助开发者将源代码编译、整合资源并打包成可执行的JAR文件。其中,"jarjar"是一个非常实用的工具,专为Java程序员设计,用于方便地对JAR文件进行操作,如重命名类...

    eclips打包成jar

    在Java开发过程中,将项目打包成可执行的JAR(Java Archive)文件是常见的操作,这使得代码可以方便地分发、部署和运行。Eclipse作为一款强大的Java集成开发环境,提供了简单易用的工具来完成这个任务。下面将详细...

    jar包修改神器.rar

    在IT行业中,jar包是Java应用程序的标准打包格式,它包含了类文件、资源文件以及元数据。当多个jar包包含相同类名时,可能会引发版本冲突问题。为了应对这种问题,"jar包修改神器"应运而生。这个压缩包文件提供了...

    jar文件管理器 模拟文件管理

    这个系统利用了Java的jar打包技术,将所有必要的类和资源打包成一个可执行的jar文件,使得用户能够方便地在计算机上进行文件管理。 【描述】中提到的“文件管理系统”是指一个软件应用,它提供了一个图形用户界面...

    jar电子书制作工具

    【标题】"jar电子书制作工具"涉及到的核心知识点主要集中在Java技术领域,特别是与Java Archive (JAR) 文件格式和移动设备应用开发相关的知识。JAR文件是Java平台上的一个特殊文件格式,它用于集合多个类文件、资源...

    集成小工具,可执行jar包

    标题中的“集成小工具,可执行jar包”指的是一个包含了一系列工具的Java应用程序,这些工具被封装在一个可执行的JAR(Java Archive)文件中。JAR文件是Java平台特有的打包格式,它允许将多个Java类文件、资源文件...

    jar转换器

    在Java环境中,JAR文件可以被用来打包和分发应用,或者实现库的依赖管理。 2. **.txt到.jar转换**:这个过程涉及到将文本文件转换为Java可执行的格式。首先,需要将txt文件编译为Java类文件,这通常通过编写Java源...

    jarjar-1.4.jar.rar

    jarjar工具便是一个这样的利器,它允许开发者将Java类进行重命名、移动或者打包到新的JAR文件中,以实现更高效、更简洁的依赖管理。本文将详细介绍jarjar-1.4版本的使用环境、功能及操作方法。 一、jarjar-1.4的...

    jar模拟器,用于在电脑上运行jar

    Java Archive(JAR)文件是Java平台上的一个特殊格式,它允许将多个Java类文件、资源文件和其他相关元数据打包成一个单一的可执行文件。JAR文件在Android平台上广泛用于存储应用程序的代码和资源,而在传统的Java...

    jarjar-1.4.jar.zip

    "jarjar-1.4.jar.zip" 文件就是为了解决这一问题而提供的工具,它可以帮助开发者重新组织和打包Java类库,避免类加载冲突。下面将详细阐述jarjar工具的工作原理、使用方法以及它如何解决jar包冲突。 **一、jarjar...

    jarjar-1.5.zip

    "jarjar-1.5.zip" 是一个工具,旨在帮助开发者解决这类问题,通过重命名或移动库中的类,使得多个版本的库能在同一个应用程序中和平共处。 JarJar是一款开源的Java工具,它的主要功能是允许开发者对Java的JAR文件...

    Jar压缩工具使大的JAR可以缩小

    JAR文件是Java平台上的一个重要的打包格式,它将多个类文件、资源文件和其他相关文件集合在一起,形成一个单一的可执行文件,方便分发和执行。 描述中的“用于手机JAVA程序,可以让手机不能装大JAR的变小”,暗示了...

    jar格式转换器

    jar文件主要用于打包Java类库、资源文件以及相关的元数据,而jad文件则是Java Micro Edition(Java ME)平台上的应用程序描述文件,它包含了运行Java应用程序所需的元数据,如类文件列表、权限设置等。对于Java ME...

    jarjar 使用示例

    `jarjar`是一款强大的Java类重打包工具,它允许我们将类库中的类进行重命名、移动或者合并,以避免类加载冲突。本文将详细介绍`jarjar`的使用方法,并通过一个实际示例来展示其在解决依赖冲突上的应用。 首先,我们...

    jar反编译工具

    Java的jar文件是一种打包格式,用于集合类、资源文件等,形成可执行的二进制文件,常用于Java应用程序和库的分发。"jar反编译工具"就是专门用来查看和理解这些二进制代码的工具,它可以帮助开发者查看jar包内部的源...

    1.7JAR包签名工具

    在Java开发中,JAR(Java Archive)文件是一种集合了类文件、资源文件和其他元数据的压缩格式,用于分发和运行Java程序。签名JAR文件是确保其完整性和来源可信的过程,这对于防止恶意代码篡改以及在移动设备或浏览器...

    jarjar-1.4.jar加使用命令txt示例

    Java开发过程中,我们经常需要对JAR文件进行操作,例如合并多个JAR文件、修改类路径或重命名类等。`jarjar`是一款强大的Java工具,它提供了方便的方式来处理这些问题。`jarjar-1.4.jar`是这个工具的一个版本,我们...

    JAR、TXT、UMD三这文件之间的转换工具

    "TXT 转换为 JAR (JBookMaker)"是一个将TXT文件转换为JAR格式的工具,允许用户将文本内容打包成一个可执行的电子书,这样可以在支持Java的设备上阅读。 UMD(Universal Mobile Book)格式是专门为手机和移动设备...

    jarjar-1.4.jar 动态更改包名

    jarjar-1.4.jar是一个Java命令行工具,它的主要功能是将一个或多个jar文件中的类文件进行重命名、移动或组合,生成新的jar包。这对于项目重构、依赖管理或解决命名冲突等问题非常有用。通过编写规则文件,用户可以...

    java软件,jar格式的

    Java软件,特别是以jar格式封装的应用程序,是Java平台上的可执行文件,广泛应用于移动设备,尤其是早期的智能手机,如那些支持Java ME (Mobile Edition)的设备。Java JAR(Java Archive)文件是一种用于打包Java类...

Global site tag (gtag.js) - Google Analytics