J2EE Shared Libraries是Weblogic Server 9.0(下简称WLS9)的一个新特性。通过J2EE
Shared Libraries可以将一个J2EE模块共享给其他企业应用(EAR包或EAR包的展开目录)的J2EE模块使用。J2EE
Shared Library可以是任何类型的J2EE模块,但推荐设计成企业应用格式。此外还有一种J2EE 1.4的标准共享库方式,称为
Optional Packages。Optional Packages提供和J2EE
Libraries类似的方式将一个JAR文件共享给多个应用。区别在于 Optional
Packages是基于标准的,但不能被当作J2EE模块使用。optional
packages必须通过部署对应的JAR文件方式先被注册到Domain。注册好后可以在任意J2EE模块中通过manifest
files来引用这些JAR包。Optional packages和J2EE libraries的区别在于optional
packages可以被任何J2EE模块(EAR, JAR, WAR, or RAR 文档)或其对应扩展的目录结构引用。而J2EE
libraries只能被企业应用引用。本文通过详细的说明将指导开发者熟悉这两种共享方式,并获得立竿见影的效果。
本文附件exercise包括J2EE Libraries 和 Optional Packages的练习代码,可解压到任意位置。需要预先安装的软件只有WLS9正式版,可以到www.bea.com.cn上
免费下载。本练习可在能安装WLS9的任何操作系统上完成,为了方便起见,文中仅以在Windows上为例。首先配置一个WLS
Domain,记得用户名和密码要都设为weblogic,端口为7001。然后启动该Domain,并启动相应的Console。最后使用
Domain/bin/setDomainEnv.cmd打开一个Prompt窗口,并把目录切换到你解压的文件的位置。这样你就可以按照第五节和六节所
述完成练习。如果想快速看一下练习结果,在solution中有已经配置好的两个练习的代码,部署后就可以测试。
共享模块的核心:MANIFEST.MF文件
我们知道在Weblogic上部署的任何J2EE模块的根目录中可以有一个名为META-INF的目录,你可以在一个J2EE模块的META-INF
目录下创建一个名为MANIFEST.MF文件,来指定这个J2EE模块的版本。MANIFEST.MF文件是一个纯文本文件,格式大概如下:
Extension-Name: myOptionalPackage
Specification-Version: 0.9
Implementation-Version: 1
Extension-Name:可选。表示该库或包的名字。主调应用调用这个应用时需要匹配这个值。如果你不设置这个值,系统将自动使用部署名。
Specification-Version:可选。定义这个库或包的规格版本。主调应用可以为共享模块随便指定一个规格版本。如果这个规格版
本不可用,则主调应用不能被部署。规格参数可以有两种格式。第一种使用主从版本格式,大小版本号用点分割,如"9.0.1.1"。第二种使用文本格式,如
"9011Beta"。如果使用主从版本号格式,主调应用可以配置为共享的模块吻合一个特定版本,或者一个最小版本,或者一个最新的版本额。如果使用文本
格式,主调应用必须和共享模块的版本号严格吻合。
Implementation-Version:可选。定义这个库或包代码的执行版本号。必须在已经定义了规格版本的情况下才能定义执行版本。执行版本使用和规格版本相同的格式。
如果你不使用MANIFEST.MF文件或者有些条目没有指定,可以在命令行中通过weblogic.Deploy进行部署的时候由参数来设
置。在后面的练习中我们将详细了解如何使用MANIFEST.MF将一个J2EE应用设计为J2EE Libraries或Optional
Packages。
J2EE Libraries and Optional Packages比较
Optional packages和J2EE Libraries有如下共同点:
1。在部署的时候都注册到Domain上。
2。都支持可选的执行版本和规格版本字符串。
3。引用J2EE libraries and optional packages的应用可以指定共享文件的版本。
Optional packages和J2EE Libraries有如下区别:
1。Optional package是普通的JAR文件,而 J2EE
libraries可以是普通JAR文件,J2EE应用,或独立的J2EE模块。J2EE
libraries可以包括有效地J2EE或WLS部署描述符,而optional package JAR中的任何部署描述符都被忽略了。
2。任何J2EE应用或模块可以通过META-INF/MANIFEST.MF引用 optional package。而只有企业应用可以通过weblogic-application.xml引用J2EE library 。
3。Optional packages可以引用其他Optional packages,而J2EE libraries不能引用其他J2EE libraries。
最佳实践
1。如果需要共享J2EE模块给多个企业应用应使用J2EE Libraries。
2。如果要部署独立的J2EE模块作为共享库,应该把模块打包到企业应用中。这样可以防止潜在的URI冲突。因为独立模块库的URI来源于不署名。所以在部署时指定一个部署名,当其他应用引用它时作为URI。
3。如果多个J2EE应用需要共享一些JAVA类,则应该用optional packages。
4。如果有一些类在本Domain中需要被其他应用调用,而你又不经常升级这些类(比如第三方类),则最好把它们放在Domain的
/lib目录下,而不是使用J2EE libraries或optional
packages机制。在/lib子目录下的类会在Server启动时候自动装载到系统环境变量中。
5。即使你不打算使用版本需要功能,通常也需要指定一个规格版本和一个执行版本。为库指定版本可以在做测试时为共享的文件部署多个版本。
6。通常为每个库指定一个扩展名,如果你不指定扩展名那系统会自动使用库的部署名作为扩展名。
7。当开发了一个Web应用要部署成J2EE应用,应该使用唯一的上下文目录。如果它的上下文目录和他依赖的应用的上下文目录冲突,应该使用EAR的weblogic-application.xml中context-root元素来覆盖库的上下文目录。
组装共享的J2EE Library 文件
几乎所有独立的J2EE模块或企业应用可以被部署成shareable J2EE library,但有如下限制:
1。不能在一个J2EE library中引用另一个J2EE library.
2。共享库不能嵌套。如果你部署一个企业应用作为共享库,那整个这个企业应用必须被作为一个库,而不能指定这个企业应用中的某个独立J2EE模块为一个独立的库。
3。像其他J2EE模块和企业应用一样,J2EE library必须被部署到目标Server或Cluster上去。这意味着库需要一个有效的J2EE部署描述符和WLS指定的部署描述符。
4。推荐把J2EE libraries打包成企业应用,而不是独立的J2EE模块。因为独立模块的URI来自于部署名。默认WLS使用部署压缩文件的文件名或展开的目录名作为部署名。
5。如果你选择把库部署成独立的J2EE模块,通常应该指定一个部署名并把这个名字作为被应用引用的URI。
练习开发和部署Shared J2EE Library
本练习在J2EEShared目录下。可以看到有两个目录,其中SharedLibraryEAR是被调用的shareable
J2EE
library,CallingLibraryEAR是调用该库的企业应用。通过把SharedLibraryEAR配置成共享库,
CallingLibraryEAR可以访问LoanEJB,就像打包在自己的企业应用中。
1.我们先来开发一个库应用。
观察一下SharedLibraryEAR下面的目录结构和文件。
目录LoanEJB是一个EJB结构。包括一个空的目录META-INF和一个包含一个JAVA文件Simple.java的目录data。
LoanEJB\data目录是放EJB的源代码,Simple.java中是我手写的一个Bean类。在目录LoanEJB下执行java
com.bea.wls.ejbgen.EJBGen -descriptorDir META-INF
data\Simple.java就会在生成SimpleHome.java,SimpleRemote.java,ejb-jar.xml,
weblogic-ejb-jar.xml和ejbgen-build.xml。然后到LoanEJB编译这几个CLASS:javac
data\*.java,生成根和桩文件。最后执行jar cvf ..\LoanEJB.jar *,打包我们需要的EJB
LoanEJB.jar到SharedLibraryEAR目录。
目录APP-INF是一个空的目录,可以放入当前这个应用需要的第三方包。
目录META-INF下包括application.xml和weblogic-application.xml。
application.xml指定了这个应用所包含的只有一个EAR模块:LoanEJB.jar,以及这个应用的部署名。为了把这个应用做成共享库,
现在我们创建一个MANIFEST.MF文件,并在里面写入如下信息:
Extension-Name: myLib
Specification-Version: 1.0
Implementation-Version: 1.0
然后在J2EEShared下执行java weblogic.appc SharedLibraryEAR,生成可部署的企业应用。
2.配置 CallingLibraryEAR来引用SharedLibraryEAR模块。
观察一下CallingLibraryEAR下面的目录结构和文件。
目录APP-INF是放企业应用内部公用的类和库的目录。在这个练习中不需要使用。
目录LoanApproval是一个Web应用。index.jsp用于调用EJB LoanEJB的getString方法,而没有指定这个EJB是来自本企业应用还是其他库。如果调用成功,则把在LoanEJB中设置的一个字符串显示在浏览器上。
目录META-INF中包括application.xml和weblogic-application.xml。
application.xml指定了这个应用所包含的只有一个Web模块LoanApproval。在weblogic-
application.xml中除了编码方式,我们还要指定使用的共享库的名称。能看到在library-ref中我们指向了
SharedLibraryEAR这个库myLib。同时在这个文件中我们还能指定库的规格版本和执行版本,以及是否需要严格匹配等。
在J2EEShared目录下执行java weblogic.appc -library SharedLibraryEAR
CallingLibraryEAR来预编译JSP。执行后会看到在LoanApproval\WEB-INF\classes下面会生成一个目录
jsp_servlet包含JSP被编译成的Servlet__index.class和__error.class。由于在weblogic-
application.xml中指定了使用的共享库,所以appc在调用jspc来编译JSP的时候能找到调用的EJB
LoanEJB的命名空间以及对应类。
3。部署共享库和前端企业应用并测试。
确保你的Server运行的情况下,在J2EEShared下执行下面两个命令来部署SharedLibraryEAR和CallingLibraryEAR。注意执行以前Console不能使被Look状态的。
java weblogic.Deployer -adminurl t3://localhost:7001 -user weblogic -password weblogic -deploy -library SharedLibraryEAR
执行之后在Console的Deployments部分能看到新添加了一个名为myLib(1.0)的库,状态为Installed。
java weblogic.Deployer -adminurl t3://localhost:7001 -user weblogic -password weblogic -deploy CallingLibraryEAR
执行之后在Console的Deployments部分能看到新添加了一个名为CallingLibraryEAR的应用,状态为Active。
如果部署成功,在Console和Server窗口都不会有报错。打开一个浏览器测试一下:http://localhost:7001/LoanApproval。如果一切正常,会显示在EJB中设置的那行字符串。
注意,当需要卸载库的时候,必须先卸载引用这个包的所有应用,然后Activate Change,然后再Look,并且卸载库。
练习开发和部署optional packages
本练习在OptionalPackages目录下。可以看到两个目录,其中SimpappOptionalPackage是被调用的Optional
Packages,SimpappEAR是调用该包的企业应用。通过把SimpappEAR配制成共享包,SimpappOptionalPackage
可以访问Simpapp类就像打包在自己的企业应用中。
- 我们先来开发一个Optional Packages。
观察一下SimpappOptionalPackage下面的目录结构和文件。
目录META-INF中现在是空的。需要创建一个MANIFEST.MF文件,包括如下内容:
Extension-Name: myOptionalPackage
Specification-Version: 0.9
Implementation-Version: 1
目录simp下面包含一个源代码文件Simpapp.java,里面包含一些业务方法。在OptionalPackages\
SimpappOptionalPackage\下执行javac
simp/Simple.java,会在simp目录下编译出Simple.class。然后执行jar cvfm simpapp.jar
META-INF/MANIFEST.MF *,把这个类打成一个名为simpapp.jar的JAR包。
- 配置SimpappEAR来引用SimpappOptionalPackage模块。
观察一下SimpappEAR下面的目录结构和文件。
目录APP-INF和我们前面说的一样,就不赘述。
目录META-INF下包括application.xml和weblogic-application.xml。
application.xml指定了这个应用所包含的只有一个Web模块SimpappWebAp。为了把这个应用做成Optional
Packages,现在我们创建一个MANIFEST.MF文件,并在里面写入如下信息:
Extension-List: simpapp
simpapp-Extension-Name: myOptionalPackage
simpapp-Extension-Specification-Version: 0.9
然后在OptionalPackages下执行java weblogic.appc -classpath
SimpappOptionalPackage/simpapp.jar
SimpappEAR,生成可部署的企业应用。注意这次我们没在appc中使用-library,因为使用 optional
packages的时候不需要获得它的部署描述符。但我们需要指定optional packages模块的位置放到classpath里编译JSP。
- 部署OptionalPackages和前端企业应用并测试。
确保你的Server运行的情况下,在OptionalPackages下执行下面两个命令来部署SimpappOptionalPackage和SimpappEAR。注意执行以前Console不能是被Look状态的。
java weblogic.Deployer -adminurl t3://localhost:7001 -user
weblogic -password weblogic -deploy -library
SimpappOptionalPackage\simpapp.jar
java weblogic.Deployer -adminurl t3://localhost:7001 -user weblogic -password weblogic -deploy SimpappEAR
如果部署成功,在Console和Server窗口都不会有报错。打开一个浏览器测试一下:http://localhost:7001/SimpappWebApp/。如果一切正常,会显示在Simple.java中设置的那行字符串。