级别: 初级 王 磊 (wanglsh@cn.ibm.com), IBM 软件工程师, IBM 戴 宣 (daixuan@cn.ibm.com), IBM 软件工程师, IBM
2009 年 4 月 27 日 JNDI(Java Naming and Directory Interface) 是 Java EE规范中定义的一组标准 API,为 Java EE 应用服务器中部署的资源提供命名与目录服务的统一访问接口,以简化应用程序对资源的引用方法。本文基于 IBM 的最新版免费应用服务器 WebSphere Application Server Community Edition(以下简称为 WAS CE)V2.1,详细介绍了 WAS CE 部署计划中与 JNDI 环境引用密切相关的内容及其使用途径,为 Java EE 应用程序开发者和应用服务器系统管理员提供了快速了解 WAS CE 的渠道。
JNDI 简介
JNDI (Java Naming and Directory Interface),即 Java 命名和目录接口。在任何一个 Jave EE 应用服务器中,JNDI 都是十分重要的组成部分。我们知道,一个 Java EE 应用服务器中往往要维护大量的资源和对象,并且它们之间很多都需要互相引用或配合以实现某种功能,这也就势必增加了程序间的耦合性,大大降低了系统的可移植性,并且难于维护。命名和目录服务将程序员从这类问题中解脱出来,它可以为 Java EE 应用服务器的各种资源和对象建立一个映射名称,并在应用程序中通过“lookup()”方法来查找到所需要的对象,这样,如果某个对象的配置有变化时,并不需要重新编译使用他的应用程序。因此,在 Java EE 规范中,JNDI 规范一直处于核心的地位。
JNDI 由两组 API 组成:API(Application Programming Interface) 和 SPI(Service Provider Interface)。JNDI API 的定义不依赖于任何特定的命名和目录服务,这使得对于各种不同的命名和目录服务,都可以使用这组通用和统一的接口调用。JNDI SPI 可以使得各种不同的命名和目录服务(如 LDAP、DNS、NIS 等)透明地加入到 JNDI 体系结构中,从而使 Java 应用程序能够通过 JNDI API 访问这些服务。
WAS CE V2.1 是遵循 Java EE 5 规范的应用服务器,它实现了上述两类接口,因此我们可以在部署到 WAS CE 的 Java EE 应用程序中使用 JNDI API 来访问各种对象和资源。
Java EE 应用程序类型与 WAS CE 部署计划
在 WAS CE V2.1 中,Java EE 应用程序主要分为以下 5 种: 表 1. Java EE 应用程序类型
|
Java EE 应用
|
存档
格式
|
部署描述符
(Deployment Descriptor)
|
部署计划
(Deployment Plan)
| |
Web Application
|
war
|
WEB-INF/web.xml
|
WEB-INF/geronimo-web.xml
| |
EJB Application
|
jar
|
META-INF/ejb-jar.xml
|
META-INF/openejb-jar.xml
| |
JCA Connectors
|
rar
|
META-INF/ra.xml
|
META-INF/geronimo-ra.xml
| |
Enterprise Application
|
ear
|
META-INF/application.xml
|
META-INF/geronimo-application.xml
| |
Enterprise Application client
|
jar
|
META-INF/application-client.xml
|
META-INF/geronimo-application-client.xml
|
从表 1 中可以看出,Java EE 5 规范针对每一种 Java EE 应用都定义了一个标准的部署描述符,用于描述 Java EE 应用的基本信息。但是,不同的应用服务器厂商在实现时,通常都会附加一些针对自身特点定制的相关配置信息来帮助 Java EE 应用在其应用服务器上的部署。在 WAS CE 中,这些信息由它的部署计划指定。因此,在一个 Java EE 应用程序中通过 JNDI 对资源的引用,也就必然的会和这两个文件产生联系。
Java EE 5 规范中的部署描述符 (Deployment Descriptor) 中引用资源的标签由以下的命名空间提供:
xmlns="http://java.sun.com/xml/ns/j2ee"
在这个 Schema 文件中定义了如表 2 所示的标签: 表 2. 部署描述符引用资源使用的标签
|
资源类型
|
标签
|
说明
| |
JCA
|
<resource-ref/>
|
描述 JCA Connection Factory 的相关信息
| |
JCA
|
<resource-env-ref/>
|
描述 JCA Administered Object 的相关信息
| |
JCA
|
<message-destination-ref/>
|
描述 JMS Destination 的相关信息,有时需要与 <message-destination/> 标签同时使用
| |
EJB
|
<ejb-ref/>
|
描述对 EJB 远程接口的引用
| |
EJB
|
<ejb-local-ref/>
|
描述对 EJB 本地接口的引用
|
由表 2 可以发现,一般可作为被引用资源的 Java EE 应用程序主要分为两种,即 JCA 连接器中定义的对象(简称 JCA 对象)与 EJB 对象。与之对应,在 WAS CE 的部署计划 (Deployment Plan) 中,也会使用如下命名空间中定义的引用资源的元素标签:
xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2"
其中详细说明如表 3 所示: 表 3. 部署计划引用资源使用的标签
|
资源类型
|
标签
|
说明
| |
JCA
|
<nam:ref-ref/>
|
可以映射一个名称到 JCA Connection Factory
如 Data Source ( 即 JDBC Connection Factory) 或 JMS 的 Connection Factory
| |
JCA
|
<nam:ref-env-ref/>
|
可以映射一个名称到 JCA Administered Object
| |
JCA
|
<nam:message-destination/>
|
可以映射一个名称到 JMS Topics 和 Queues
| |
EJB
|
<nam:ejb-ref/>
|
可以映射一个名称到 EJB 的 remote interface
| |
EJB
|
<nam:ejb-loc-ref/>
|
可以映射一个名称到 EJB 的 local interface
|
在 Java EE 应用程序中编写用 JNDI 引用资源相关代码的前提条件,就是要把这两个文件中的对应信息正确的联系起来。不仅如此,在它的部署计划中,还需要把资源所在的包作为依赖引入进来,元素标签由以下的命名空间指定:
xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2"
下面我们就从这两种引用对象类型以及三个命名空间着手进行分析,以说明它们之间的联系。
注:下文部署计划中出现的以 "<dep:" 和 "<nam:" 开头的元素标签请参照本节前面指出的命名空间定义。
JNDI 对 JCA 对象的引用
数据库连接池 (Database pool)
创建方法
在 WAS CE V2.1 中,我们有两种方式可以创建一个数据库连接池:
-
通过 Wizard 创建数据库连接池:
进入 Web Console 的 Database Pools Portlet,点击 Portlet 页面中的 "Using the Geronimo database pool wizard" 链接,可以根据提示一步一步的创建数据库连接池。
-
编写数据库连接池的部署计划 (plan-pool.xml),通过以下两种途径部署均可:
进入 GShell,运行如下面命令:
deploy/deploy
repository/org/tranql/tranql-connector-derby-embed-local/1.4/
tranql-connector-derby-embed-local-1.4.rar
c:/plan-pool.xml
|
注:在 Gshell 中请把它们写在一行里,并且必须使用 "/" 作为路径分隔符。
进入 Web Console 的 Deploy New Portlet,选择前面 GShell 命令中指出的路径下的 tranql-connector-derby-embed-local-1.4.rar 及 plan-pool.xml。
部署计划分析
在用于创建数据库连接池的部署计划 (plan-pool.xml) 中,如下片段定义了数据库连接池的名称:
清单 1. 数据库连接池包的名称 TestPool
<dep:moduleId>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestPool</dep:artifactId>
<dep:version>2.1.1.1</dep:version>
<dep:type>rar</dep:type>
</dep:moduleId>
|
在这个部署计划中也同时定义了数据源 (Data Source) 对象的名称:
清单 2. 数据源名称定义 TestDS
<resourceadapter>
<outbound-resourceadapter>
<connection-definition>
<connectionfactory-interface>javax.sql.DataSource</connectionfactory-interface>
<connectiondefinition-instance>
<name>TestDS</name>
|
通过上节中的两种方法创建的数据库连接池有一点微妙的差别,那就是第一种方法创建的数据库连接池的名称与数据源 (Data Source) 名称往往是相同的。而在第二种方法中,则可以在 <artifactId> 和 <connectiondefinition-instance> 中分别指定,从而在引用时区别开来。这是因为第一种方法产生的部署计划是由 Wizard 自动生成的,目的是为了提升用户体验,从而简化了一些步聚,但同时,也就降低了配置的灵活性。也就是说在第一种方法中,我们不能自定义 <moduleId/> 中的内容,因此我们也可以注意到,通过 Wizard 产生的部署计划中,总是默认 groupId 为 console.dbpool,version 为 1.0,type 为 rar。
在 Java EE 应用程序中引用数据库连接池中的数据源对象的一般步骤
- 在应用程序的部署计划中加入依赖,指明数据源对象 TestDS 所在的包 TestPool 的信息:
<dep:dependency>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestPool</dep:artifactId>
<dep:version>2.1.1.1</dep:version> <dep:type>rar</dep:type>
</dep:dependency>
|
-
在应用程序的部署计划中为数据源对象创建引用名称,定义数据源对象 TestDS 的引用名称为 jdbc/DataSource:
<nam:resource-ref>
<nam:ref-name>jdbc/DataSource</nam:ref-name>
<nam:resource-link>TestDS</nam:resource-link>
</nam:resource-ref>
|
-
同时,在应用程序的部署描述符中加入下面信息,声明引用名称 jdbc/DataSource 的相关信息:
<resource-ref>
<res-ref-name>jdbc/DataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
|
-
应用程序中使用 JNDI 引用对象,查询名称
java:comp/env/jdbc/DataSource。
import javax.naming.*;
......
Context initContext = new InitialContext();
DataSource ds = (DataSource)initContext.lookup("java:comp/env/jdbc/DataSource");
|
JMS 资源组 (JMS Resource Group)
创建方法
在 WAS CE 中,同样有两种方法可以创建一个 JMS 资源组:
-
通过 Wizard 创建 JMS 资源组:
进入 Web Console 的 JMS Resources Portlet,点击 Portlet 页面中的 "Create a new JMS Resource Group: For ActiveMQ" 链接,可以一步一步的根据提示创建 JMS 资源组。
-
编写 JMS 资源组的部署计划(plan-jms.xml),通过以下两种途径部署:
进入 GShell,运行如下面命令:
deploy/deploy
repository/org/apache/geronimo/modules/geronimo-activemq-ra/2.1.3/
geronimo-activemq-ra-2.1.3.rar
c:/plan-jms.xml
|
-
进入 Web Console 的 Deploy New Portlet,选择前面 GShell 命令中指出的路径下的 geronimo-activemq-ra-2.1.3.rar 及 plan-jms.xml。
部署计划分析
在用于创建 JMS 资源组的部署计划 (plan-jms.xml) 中,如下片段定义了 JMS 资源组的名称:
清单 3. JMS 资源组的名称 TestRG
<dep:moduleId>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestRG</dep:artifactId>
<dep:version>2.1.1.1</dep:version>
<dep:type>rar</dep:type>
</dep:moduleId>
|
同时,指定了资源适配器 (Resource Adapter) 的名称,连接工厂 (Connection Factory) 的名称,以及消息目的地 (message destination) 的名称:
清单 4. JMS 相关几种对象的名称:TestRG, TestCF 和 TestQueue
<resourceadapter>
<resourceadapter-instance>
<resourceadapter-name>TestRG</resourceadapter-name>
…
<outbound-resourceadapter>
<connection-definition>
<connectionfactory-interface>javax.jms.QueueConnectionFactory
</connectionfactory-interface>
<connectiondefinition-instance>
<name>TestCF</name>
…
<adminobject>
<adminobject-interface>javax.jms.Queue</adminobject-interface>
<adminobject-class>org.apache.activemq.command.ActiveMQQueue</adminobject-class>
<adminobject-instance>
<message-destination-name>TestQueue</message-destination-name>
…
|
同前面关于数据库连接池的描述相似,通过这两种方法创建的 JMS 资源组也存在着些许差别。即第一种方法中创建的 JMS 资源组名称与资源适配器 (Resource Adapter) 名称相同,而在第二种方法中,则可以分别由 <artifactId> 及 <resourceadapter-name> 指定,从而在引用时区别开来。同样,在第一种方法中,不能自定义配置 <moduleId/> 中的内容,它默认产生的 groupId 为 console.jms,version 为 1.0,type 为 rar。
在 Java EE 应用程序中引用 JMS 资源的一般步骤
1. 在应用程序的部署计划中加入依赖,指明 JMS 资源组所在的包 TestRG 的信息。
<dep:dependency>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestRG</dep:artifactId>
<dep:version>2.1.1.1</dep:version>
<dep:type>rar</dep:type>
</dep:dependency>
|
2. 在应用程序的部署计划中为 JMS 资源指定引用名称。
-
定义连接工厂 TestCF 的引用名称为 jms/ConnectionFactory。
<nam:resource-ref>
<nam:ref-name>jms/ConnectionFactory</nam:ref-name>
<nam:resource-link>TestCF</nam:resource-link>
</nam:resource-ref>
|
-
定义消息目的地 TestQueue 的引用名称为 jms/Queue。
<nam:resource-env-ref>
<nam:ref-name>jms/Queue</nam:ref-name>
<nam:admin-object-link>TestQueue</nam:admin-object-link>
</nam:resource-env-ref>
|
3. 同时,在应用程序的部署描述符中加入下面信息。
-
声明连接工厂 jms/ConnectionFactory 的相关信息。
<resource-ref>
<res-ref-name>jms/ConnectionFactory</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
|
-
声明消息目的地 jms/Queue 的相关相息
<resource-env-ref>
<resource-env-ref-name>jms/Queue</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
|
注:我们也可以在部署描述符中用下面这种形式直接定义 TestQueue 的引用。 jms/Queue,这样便不需要在部署计划中重复定义,如下所示:
<message-destination-ref>
<message-destination-ref-name>jms/Queue</message-destination-ref-name>
<message-destination-type>javax.jms.Queue</message-destination-type>
<message-destination-usage>Produces</message-destination-usage>
<message-destination-link>TestQueue</message-destination-link>
</message-destination-ref>
|
如果你还是想在部署描述中使用其它的引用名称 ( 如 TestDestination),而不是直接指向 TestRG 中定义的 TestQueue 对象的话,则需要在部署计划中加入如下片段:
<nam:message-destination>
<nam:message-destination-name>TestDestination</nam:message-destination-name>
<nam:admin-object-link>TestQueue</nam:admin-object-link>
</nam:message-destination>
|
同时在部署描述符中加入:
<message-destination>
<message-destination-name>TestDestination</message-destination-name>
</message-destination>
|
并且将部署描述符中的 message-destination-link 的值设置为 TestDestination。
4. 应用程序中通过 JNDI 引用对象 JMS 对象,查询名称 java:comp/env/jms/ConnectionFactory 以及 java:comp/env/jms/Queue
import javax.naming.*;
…
InitialContext context = new InitialContext();
QueueConnectionFactory connectionFactory =
(QueueConnectionFactory) context.lookup("java:comp/env/jms/ConnectionFactory");
Queue queue = (Queue) naming.lookup("java:comp/env/jms/Queue");
|
JNDI 对 EJB 对象的引用
被引用的 EJB 类型
我们知道,EJB 有三种类型:实体 Bean(Entity Bean),会话 Bean(Session Bean),消息驱动 Bean(Message Driven Bean)。但是通常情况下,只有实体 Bean 及会话 Bean 会作为被引用对象出现在 Java EE 应用程序的部署计划中。在本文中,我们以会话 Bean 为例。
通过 JNDI 引用会话 Bean
创建方法
在 EJB3.0 中,大部份部署描述符所作的声明都可以通过在 Bean 的类中使用对应的 annotation 来代替,比如:
@Stateless/@Stateful 可以声明一个 Bean 是无状态会话 Bean(Stateless Session Bean) 或有状态会话 Bean(Stateful Session Bean)。
@Remote 声明一个 Bean 的远程接口 (Remote interface)。
@Local 声明一个 Bean 的本地接口 (Local interface)。
但是,为了更明确的阐述本文所讨论的问题,仍然提供了此会话 Bean 的部署计划和部署描述符,见下节。
部署计划和部署描述符分析
在部署计划 openejb-jar.xml 中,如下片段定义了这个 EJB 应用的名称:
清单 5. EJB 应用的名称
<dep:moduleId>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestEJB</dep:artifactId>
<dep:version>2.1.1.1</dep:version>
<dep:type>jar</dep:type>
</dep:moduleId>
|
在部署描述符 ejb-jar.xml 中,如下片段定义了会话 Bean 的基本构成:
清单 6. 会话 Bean 的基本信息
<session>
<ejb-name>TestBean</ejb-name>
<business-remote>com.ibm.wasce.samples.TestBeanRemote</business-remote>
<business-local>com.ibm.wasce.samples.TestBeanLocal</business-local>
<ejb-class>com.ibm.wasce.samples.TestBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
|
由此我们可以看出,这个 EJB 是一个无状态会话 Bean,它的实现类是 TestBean,远程接口为 TestBeanRemote,本地接口为 TestBeanLocal。
在 Java EE 应用程序中引用会话 Bean 的一般步骤
1. 在应用程序的部署计划中加入依赖,指明会话 Bean 所在的 EJB 应用包 TestEJB 的信息
<dep:dependency>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestEJB</dep:artifactId>
<dep:version>2.1.1.1</dep:version>
<dep:type>jar</dep:type>
</dep:dependency>
|
2. 在应用程序的部署计划中为要引用的 EJB 创建引用名称,定义 TestBean 的引用名称为 ejb/SessionBean
-
若需要使用 EJB 的远程接口,则添加如下片段:
<nam:ejb-ref>
<nam:ref-name>ejb/SessionBean</nam:ref-name>
<nam:ref-link>TestBean</nam:ref-link>
</nam:ejb-ref>
|
-
若需要使用 EJB 的本地接口,则添加如下片段:
<nam:ejb-local-ref>
<nam:ref-name>ejb/SessionBean</nam:ref-name>
<nam:ejb-link>TestBean</nam:ejb-link>
</nam:ejb-local-ref>
|
3. 同时,在应用程序的部署描述符中声明引用名称 ejb/SessionBean 的相关信息。
-
若需要使用 EJB 的远程接口,则添加如下片段:
<ejb-ref>
<ejb-ref-name>ejb/SessionBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<remote>com.ibm.wasce.samples.TestBeanRemote</remote>
</ejb-ref>
|
-
若需要使用 EJB 的本地接口,则添加如下片段:
<ejb-local-ref>
<ejb-ref-name>ejb/SessionBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.ibm.wasce.samples.TestBeanLocal</local>
</ejb-local-ref>
|
4. 应用程序中通过 JNDI 引用对象,以使用远程接口为例:
import com.ibm.wasce.samples.TestBeanRemote;
…
InitialContext context = new InitialContext();
TestBeanRemote testBean = (TestBeanRemote) naming.lookup("java:comp/env/ejb/SessionBean");
|
全局 JNDI 上下文
在 WAS CE 中,前两节介绍的通过 JNDI 引用的 Java EE 对象在其部署时都会被自动的绑定到 Server 的全局 JNDI 上下文 (Global JNDI Context) 里。全局上下文可以通过 Web Console 的 JNDI Viewer Portlet 浏览与查询。
JCA 对象
此类对象如上文中的 Data Source, JMS Connection Factory, AdminObject 等。他们在全局 JNDI 上下文中的命名形式为:
jca:/groupId/artifactId/jeeType/name
其中:
groupId/artifactId 为部署 JCA 对象时其部署计划中指定的名称
jeeType 一般为 JCAManagedConnectionFactory 或 JCAAdminObject
name 为部署计划中指定的对象名称
以前文所描述的 JCA 对象为例,它们分别为:
-
数据源对象
jca:/console.dbpool/TestPool/JCAManagedConnectionFactory/TestDS
|
-
JMS 连接工厂
jca:/console.jms/TestRG/JCAManagedConnectionFactory/TestCF
|
-
JMS 消息目的地
jca:/console.jms/TestRG/JCAAdminObject/TestQueue
|
EJB 对象
只有会话 Bean 与实体 Bean 会被自动绑定到全局 JNDI 上下文。默认的命名形式为:
"ejbName"+"interfaceType.annotationName"
其中:
ejbName 由 EJB 的部署描述符 ejb-jar.xml 中指定或通过在 EJB 的实现类中使用 annotation ( 如 @Stateful/@Stateless 等中设定 name 属性 ) 指定。
interfaceType.annotationName 在 EJB3.0 中为 "Remote" 或 "Local"
其它更详细的信息请参考 OpenEJB 官方文档。
通过 Annotation 引用对象
根据 Java EE 5 规范,我们可以利用 Annotation,使得应用程序可以更方便的引用 Java EE 对象,其本质上与 JNDI 引用是相同的,只是对编程方式的一种简化。
通过 Annotation 在 Java EE 应用中引用 JCA 对象
首先要我们要在 Java EE 应用程序中导入以下包:
import javax.annotation.Resource;
以前文描述的 JCA 对象为例,在应用程序中使用 annotation 的方法分别为:
-
数据源对象
@Resource(name = "jdbc/DataSource")
private DataSource ds;
|
-
JMS 连接工厂
@Resource(name="jms/TestConnectionFactory")
private QueueConnectionFactory connectionFactory;
|
-
JMS 消息目的地
@Resource(name="jms/TestQueue")
private Queue queue;
|
通过 Annotation 在 Java EE 应用中引用 EJB 对象
首先要我们在要应用程序的类中导入以下包:
import javax.ejb.EJB;
以前文描述的会话 Bean 为例,在应用程序中使用 annotation 的方法为:
@EJB(name = "ejb/SessionBean")
private TestBeanRemote testBean;
|
应用程序上下文
由前文所述可以发现,通过 JNDI 引用对象时通常有以下形式:
initContext.lookup("java:comp/env/JNDI_NAME");
这个 java:comp/env 上下文表示的是在当前的应用程序上下文里对名为 JNDI_NAME 的 Java EE 对象进行查找。当前应用程序的上下文包括当前的应用程序本身以及它的部署计划中指明的依赖 (dependencies)。lookup 方法首先会在当前应用程序中查找对象,如果找到了就不会在再去它的依赖中尝试;如果没有,则会继续查找其依赖的应用程序,这要求字符串 JNDI_NAME 在所有的依赖中必须是唯一的。
依据以上规则,当应用程序是一个 EAR 时,如果它所包含的 Web 应用引用了同样在这个 EAR 中部署的 RAR 应用中的资源 ( 或 EJB 应用中的 Bean),我们是不用在 Web 应用的部署计划中指明这个 RAR/EJB 应用为其的依赖。否则,如果他们之间是相互独立的应用程序,必须在部署计划中指明依赖。
在部署计划中为对象定义引用名称不是必需的,也就是说,如果 JNDI_NAME 直接使用的就是所引用对象的名称,则可以省略此定义。比如在部署描述符中有如下定义:
<resource-ref>
<res-ref-name>TestDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
|
并且 TestDS 是部署计划中声明的如下依赖 (TestPool) 中定义的数据源名称:
<dep:dependency>
<dep:groupId>com.ibm.wasce.samples</dep:groupId>
<dep:artifactId>TestPool</dep:artifactId>
<dep:version>2.1.1.1</dep:version>
<dep:type>rar</dep:type>
</dep:dependency>
|
则我们不需要在部署计划中定义:
<nam:resource-ref>
<nam:ref-name>TestDS</nam:ref-name>
<nam:resource-link>TestDS</nam:resource-link>
</nam:resource-ref>
|
另外,在部署计划中为对象定义引用名称时,其指向对象的名称必须在当前应用程序上下文中是唯一的,比如如下定义:
<nam:ejb-ref>
<nam:ref-name>ejb/SessionBean</nam:ref-name>
<nam:ref-link>TestBean</nam:ref-link>
</nam:ejb-ref>
|
其中 TestBean 必须在当前应用程序及其依赖中是唯一的,否则就需要借助 <pattern/> 标识为对象进行定位。
清单 7. 使用 pattern 定位对象
<nam:ejb-ref>
<nam:ref-name>ejb/SessionBean</nam:ref-name>
<pattern>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>version</version>
<type>type</type>
<name>name</name>
</pattern>
</nam:ejb-ref>
|
其中 groupId/artifactId/version/type 对应其应用程序上下文中的某个 moduleId 中的定义,name 为引用对象的名称。
结束语
本文详细介绍了 WAS CE 部署计划与 JNDI 环境引用之间的联系,并且对 Java EE 应用程序中通过 JNDI 引用资源的方法进行了总结,归纳为四个步骤:
-
在部署计划中指明依赖
-
在部署计划中定义引用名称
-
在部署描述符中声明引用名称的相关信息
-
在 Java EE 应用程序中通过 JNDI 的”lookup()”方法引用对象
同时,本文也向开发者介绍了全局 JNDI 上下文,通过 Annotation 引用对象,以及应用程序上下文的相关概念及要点,希望能为读者提供一个快速了解 WAS CE 的有效途径。
参考资料 学习
获得产品和技术
作者简介  | |  | 王磊,毕业于上海交通大学,获得计算机科学硕士学位。IBM 中国软件开发中心 WAS CE 开发团队成员,参与了 WAS CE 应用服务器多个版本的开发工作,拥有丰富的 Java EE 经验。 |
 | |  | 戴宣,毕业于东南大学,获得计算机科学硕士学位。IBM 软件工程师,热衷计算机网络技术、Eclipse 插件开发及 Java EE 相关技术。现为IBM 中国软件开发中心 WAS CE 开发团队成员。 |
对本文的评价
|