级别: 中级 Matthew Leming, WebSphere 消息传递开发, IBM Graham Hopkins, 首席测试师, IBM
2009 年 8 月 26 日
通道出口是运行在 IBM® WebSphere® MQ 通道生命周期中被指定的点上的用户代码。通道出口有许多可能的用法,包括审计、安全、压缩、转换等等。在 WebSphere Application Server V7 之前,通道出口没有得到完整的支持,但是现在可以在连接工厂和激活规范上配置通道出口。本文介绍通道出口的类型、使用限制,以及如何在应用服务器和应用客户端环境中实现它们。
来自 IBM WebSphere Developer Technical Journal。
简介
IBM WebSphere Application Server V7 中的 IBM WebSphere MQ 消息提供程序提供对基于 Java™ 通道出口的完整支持。道出口是运行在 IBM® WebSphere® MQ 通道生命周期中被指定点上的用户代码。通道出口有许多可能的用法,包括审计、安全、压缩、转换等等。
之前的 WebSphere Application Server 版本中,通道出口没有得到完整的支持,必须通过定制属性配置。在 WebSphere Application Server V7 中,通道出口可以使用管理控制台或管理命令配置连接工厂和激活规范指定,也可以使用客户端通道定义表 (CCDT) 条目指定。
通道出口类型
WebSphere MQ 消息提供程序支持三种不同的通道出口:安全、发送和接受出口。每种出口类型都在客户端连接通道的不同时点调用,如表 1 所示。
表 1. 通道出口调用时间
| 出口类型 | 何时调用构造函数 |
|---|
|
安全出口
|
- 通道初始化时。
- 如果从安装在服务器连接通道的安全出口接收安全流。
| |
发送出口
|
- 通道初始化时。
- 在任何数据发送到队列管理程序之前。
| |
接收出口
|
- 通道初始化时。
- 从队列管理程序收到数据之后,且在将该数据传递到应用程序之前。
|
 | |
您可以点击如下链接,马上下载 WebSphere Application Server 软件 v7 版本,体验其为您带来的新特性及新功能。
更多关于 WebSphere Application Server 的技术资源,请参考:
|
|
发送和接收出口支持链;即可以对 WebSphere MQ 消息提供程序资源指定多个发送和接收出口。如果使用链,则调用链中的第一个出口,返回的数据将传递到链中的下一个出口。在调用所有出口之前该操作将一直持续,然后将数据发送到相应的队列管理程序或客户端。
正如上文所述,如果相应服务器连接通道上的安全出口发送了一个安全流,那么仅调用安全出口 WebSphere MQ 消息提供程序上安装的安全出口。由于仅在通道启动时调用安全出口,安全出口对于执行只需执行一次的功能非常理想。顾名思义,这通常意味着执行验证。图 1 显示启动驱动时将调用的安全出口。
图 1. 安全出口调用
在通过队列管理程序发送和接收数据之前,应该分别调用发送方和接收方通道出口。这些出口类型常见的用法包括:计算发送或接收数据的数量,或者执行某种形式的数据转化,比如压缩。如果有必要,可以在通道的任何一端安装互补的发送和接收出口。例如,如果使用出口执行数据压缩,那么在执行解压缩时在两端都需要接收出口。如图 2 所示。
图 2. 互补的发送和接收出口
有关何时何地调用通道出口的更多信息,请参见 参考资料。
通道出口使用限制
使用通道出口和 WebSphere MQ 消息提供程序时有一些必须注意的限制:
- 为了利用通道出口,WebSphere MQ 消息提供程序连接工厂和激活规范的传输类型必须为 client 或 bindings-then-client。这是因为只有在使用客户端连接通道连接到 WebSphere MQ 队列管理程序或队列共享组时才使用通道出口程序。如果选择了 bindings-then-client 传输模式,那么只有在绑定模式连接失败时才使用通道出口。
- 除了 Java 之外,WebSphere MQ 支持以各种编程语言编写的通道出口,包括 C 和 C++。但是,WebSphere MQ 消息提供程序仅支持基于 Java 的通道出口,因此不能使用 C 和 C++ 通道出口。
- 使用通道出口的 WebSphere MQ 消息提供程序资源根据第一次使用资源的应用程序类路径加载通道出口类。如果 IBM 没有推荐其他资源,请确保遵守有关指定加载通道出口资源地点的 WebSphere MQ 文档。有关带有 WebSphere MQ 消息提供程序的通道出口的类加载考虑事项,将在本文的下一节介绍。
编写简单的通道出口
创建使用 WebSphere MQ 消息提供程序的通道出口需要实现一个或多个 Java 通道出口界面。有两个接口集:一个为 WebSphere MQ V7 引用,提供增强的性能和功能;另一个从 WebSphere MQ V5 开始可用。两个接口都可以用于 WebSphere MQ 消息提供程序,但是本文中的示例将仅使用新接口。
不管使用的是哪种接口集,它们都遵从相同的模式。一个接口提供给每种通道出口,每个接口都提供一个需要实现的方法。接口和方法签名如表 2 所示。
表 2. 通道出口接口定义
| 接口类型 | 接口名称 | 接口方法 |
|---|
|
新发送出口
| com.ibm.mq.exits.WMQSendExit | public ByteBuffer channelSendExit(MQCXP
channelExitParms, MQCD channelDefinition, ByteBuffer agentBuffer)
| |
新接收出口
| com.ibm.mq.exits.WMQReceiveExit | public ByteBuffer channelSendExit(MQCXP
channelExitParms, MQCD channelDefinition, ByteBuffer agentBuffer)
| |
新安全出口
| com.ibm.mq.exits.WMQSecurityExit | public ByteBuffer channelReceiveExit( MQCXP
channelExitParms, MQCD channelDefinition, ByteBuffer agentB | |
原来的发送出口
| com.ibm.mq.MQSendExit | public byte[] sendExit(MQChannelExit
channelExitParms, MQChannelDefinition channelDefinition, byte[]
agentBuffer) | |
原来的接收出口
| com.ibm.mq.MQReceiveExit | public byte[] receiveExit(MQChannelExit
channelExitParms, MQChannelDefinition channelDefinition, byte[]
agentBuffer) | |
原来的安全出口
| com.ibm.mq.MQSecurityExit | public byte[] securityExit(MQChannelExit
channelExitParms, MQChannelDefinition channelDefinition, byte[]
agentBuffer) |
如果要使用新样式出口,则在编写和编译通道出口时需要 com.ibm.mq.jmqi.jar 副本,如果要使用较旧样式出口,那么需要 com.ibm.mq.jar 副本。这些 jar 文件可以直接从 <WAS_INSTALL_ROOT>/lib/WMQ/ra/ 获取,也可以从 WebSphere MQ 安装中获取。
每个出口最简单的形式是使用出口接口方法返回传入的 agentBuffer 参数。清单 1 中展示的类提供了这三种出口最基本的实现。本文的剩下部分将引用该示例。
清单 1
package com.ibm.ce;
<IMPORTS REMOVED>
/**
* A simple channel exit that provides an implementation of a send,
* receive and security exit.
*/
public class LoggingChannelExit implements WMQSendExit, WMQReceiveExit, WMQSecurityExit
{
/**
* Send exit implementation.
*/
public ByteBuffer channelSendExit(MQCXP channelExitParms,
MQCD channelDefinition,
ByteBuffer agentBuffer)
{
System.out.println("Send Exit Invoked");
return agentBuffer;
}
/**
* Receive exit implementation.
*/
public ByteBuffer channelReceiveExit(MQCXP channelExitParms,
MQCD channelDefinition,
ByteBuffer agentBuffer)
{
System.out.println("Receive Exit Invoked");
return agentBuffer;
}
/**
* Security exit implementation.
*/
public ByteBuffer channelSecurityExit(MQCXP channelExitParms,
MQCD channelDefinition,
ByteBuffer agentBuffer)
{
System.out.println("Security Exit Invoked");
return agentBuffer;
}
} |
创建和安装通道出口时,每个定义的出口最多可以传入 32 个字符的数据,可以用于配置目的。在新的样式接口中,可以通过 MQCXP.getUserData() 方法访问该数据,该方法将返回一个字符串。下一节将展示如何设置这个出口数据。
在 WebSphere 消息提供程序资源上配置通道出口
用来指定特定 WebSphere MQ 消息提供程序运行哪个通道出口的步骤取决于该资源是否基于 CCDT 中的信息。如果资源以 CCDT 为基础,那么将在创建 CCDT 时制定通道出口信息。图 3 展示了如何使用 WebSphere MQ Explorer 工具向客户端连接通道定义添加上文定义的简单通道出口程序。(有些用户数据已经在此指定,但在本例中,通道出口实现不使用它)。
图 3. 在 CCDT 上配置通道出口
如果向非 CCDT 定义的 WebSphere MQ 消息提供程序资源添加通道出口,那么可以使用管理控制台或 wsadmin 命令行工具。
如果使用管理控制台:
- 登录管理控制台并导航到基于非 CCDT 的相关 WebSphere MQ 消息提供程序激活规范或连接工厂。
- 如图 4 所示,单击 Additional 属性下方面板右边的 Client transport properties 链接。
图 4. 客户端传输属性
- 在相关的通道出口字段,输入通道出口类的完整名称,包括包。在本例中,输入
com.ibm.ce.LoggingChannelExit。如果需要多个发送和接收出口,则使用逗号分隔名称。
- 在相关用户数据字段输入任何用户数据。如果定义了多个通道出口,则可以定义多个以逗号分隔的用户数据集。如果定义的通道出口多于用户数据,则剩余通道出口的用户数据将为空字符串。类似地,如果输入两个逗号作为用户数据,那么列表中该位置的通道出口将获取由空白字符串组成的用户数据。
- 单击 OK 保存更改。
在应用服务器环境资源中使用支持通道出口的资源
编写企业应用程序使用配置为使用通道出口的 WebSphere MQ 消息提供程序资源时,您必须小心确保消息提供程序可以加载通道出口实现。本节介绍如何在应用程序服务器环境中实现这一点,下一节将解释如何让通道出口实现类可用于应用程序客户端环境。
如果 WebSphere MQ 消息提供程序激活规范或连接工厂的实例已经使用通道出口配置,那么在创建激活规范或实现类时,消息提供程序将尝试使用映像加载通道出口实现类。为了实现这一点,通道出口实现类必须可用于 WebSphere MQ 消息提供程序运行时使用的类加载程序。可以用三种方式实现:
- 最简单的方法是让通道出口类可用于整个应用服务器运行时加载,向应用服务器类路径添加类即可实现。但是,不建议使用该方法,因为它可能导致加载类的实际位置不明确,尤其是在一个应用服务器中使用多个版本的相同类时。
- 第二种方法是,每个应用程序可以使用其内部绑定的通道出口类副本进行部署(部署为 JAR 或一个或多个其他类文件。如果只有一个应用程序使用通道出口配置的 WebSphere MQ 消息提供程序连接工厂或激活规范,那么这种方法更加合理。但是,在大部分情况下(尤其是通道出口广泛使用时),该方法不是很合适,因为它增加了应用程序的大小,并且使通道出口实现升级时间过长,且容易出错。
- 第三种常用的方法是将通道出口实现作为共享库提供,使需要的应用程序能够访问它们。这种方法意味着应用程序开发人员不需要意识到使用通道出口,此外,它有助于防止类路径过于臃肿,在通道出口实现更改时还提供了一个简单的升级战略。在 WebSphere Application Server 中使用标准库的办法由几种:您可以使用共享库引用,或者使用 WebSphere Application Server V7 中引入的新资产支持。
当企业应用程序使用配置为使用通道出口的 WebSphere MQ 消息提供程序资源时,通道出口实现不可用于应用程序类路径,结果生成一个带有 2406 错误代码的 MQException。清单 2 展示了一个发生这种情况的示例。在该清单中,应用程序尝试使用配置为使用 LoggingChannelExit 类作为发送出口的 WebSphere MQ 消息提供程序工厂。当在应用服务器环境中运行时,这些异常一般包含在一个或多个 First Failure Data Capture (FFDC) 记录中。
清单 2
com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2'
('MQCC_FAILED') reason '2406' ('MQRC_CLIENT_EXIT_LOAD_ERROR').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:206)
... 30 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2406;AMQ9535: User exit not valid.
[1=com.ibm.ce.LoggingChannelExit]
at com.ibm.mq.jmqi.remote.internal.RemoteExitChain.loadJavaExitByName
(RemoteExitChain.java:1858)
at com.ibm.mq.jmqi.remote.internal.RemoteExitChain.loadByName
(RemoteExitChain.java:1816)
at com.ibm.mq.jmqi.remote.internal.RemoteExitChain.parseSendReceiveExitsChain
(RemoteExitChain.java:1655)
at com.ibm.mq.jmqi.remote.internal.RemoteExitChain.loadExits
(RemoteExitChain.java:824)
at com.ibm.mq.jmqi.remote.internal.RemoteHconn.initSendReceiveExits
(RemoteHconn.java:683)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnectionPool.getConnection
(RemoteConnectionPool.java:295)
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1371)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:331)
... 29 more
Caused by: java.lang.ClassNotFoundException: com.ibm.ce.LoggingChannelExit
at java.net.URLClassLoader.findClass(URLClassLoader.java:419)
at java.lang.ClassLoader.loadClass(ClassLoader.java:643)
at java.lang.ClassLoader.loadClass(ClassLoader.java:609)
at com.ibm.mq.jmqi.remote.internal.RemoteExitChain.loadJavaExitByName
(RemoteExitChain.java:1855)
... 36 more |
以下步骤展示了如何使用共享库,使企业应用程序可以使用经过通道出口配置的 WebSphere MQ 消息提供程序连接工厂或激活规范。
- 从 WebSphere Application Server 管理控制台导航到 Applications => Application Types => WebSphere
enterprise applications,然后单击将使用支持通道出口的 WebSphere MQ 消息提供程序资源的应用程序。
- 如图 5 所示,单击 References 区域的 Shared library references。选择将使用 WebSphere MQ 消息提供程序资源的应用程序模块,然后单击 Reference shared libraries 按钮。
图 5. 定制属性
- 如果没有定义相关的共享库,那么单击 New 按钮(图 5 圆圈处)。这将显示一个面板,用于输入可以用来定位出口库的类路径信息。输入信息并单击 OK。
- 从 Available 列表中选择库,然后使用箭头按钮将它移动到 Selected 列表(图 6)。单击 OK,再单击 OK。
图 6. 共享库映射
- 最后,保存更改并重启应用服务器。
当再次运行企业应用程序时,它应该能够使用支持通道出口的 WebSphere MQ。例如,使用配置为使用 LoggingChannelExit 类作为发送出口的 WebSphere MQ 消息提供程序连接工厂时要谨慎。这将输出清单 3 中所示的应用服务器日志。
清单 3. LoggingChannelExit 输出
[05/10/08 16:06:02:736 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:861 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:877 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:877 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:877 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:877 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:877 BST] 00000010 SystemOut O Send Exit Invoked
[05/10/08 16:06:02:986 BST] 00000010 SystemOut O Send Exit Invoked |
在应用程序客户端环境中使用支持通道出口的资源
在客户端环境中使用 WebSphere MQ 消息提供程序连接工厂时,类加载考虑事项比服务器环境要简单地多。通道出口类或 JAR 要么是客户端应用程序的一部分,要么调整客户端应用程序类路径,使其包含对外部通道出口类或 JAR 的引用。这种情况下的最佳方法是使用 launchClient 命令的 -CCclasspath 属性引用外部 JAR 或类集合,如清单 4 所示。
清单 4. 使用 launchClient 指定类路径信息
C:\was7gm\profiles\AppSrv01\bin>launchClient.bat client.ear -CCclasspath=c:\exits\
2809 m1
IBM WebSphere Application Server, Release 7.0
Java EE Application Client Tool
Copyright IBM Corp., 1997-2008
WSCL0012I: Processing command line arguments.
WSCL0013I: Initializing the Java EE Application Client Environment.
[05/10/08 16:18:00:002 BST] 00000000 W UOW=null source=com.ibm.ws.ssl.config.SSLConfig
org=IBM prod=WebSphere component=Application Server thread=[P=879377:O=0:CT]
CWPKI0041W: One or more key stores are using the default password.
WSCL0035I: Initialization of the Java EE Application Client Environment has completed.
WSCL0014I: Invoking the Application Client class Main
Send Exit Invoked
Send Exit Invoked
Send Exit Invoked |
结束语
WebSphere Application Server V7.0 中的 IBM WebSphere MQ 消息提供程序使部署直接利用 WebSphere MQ 企业消息功能的 Java EE 应用程序成为可能。本文概述了通道出口、介绍了它们的好处和使用限制,并提供一些演示如何在应用服务器和应用程序客户端环境中实现它们的示例。
参考资料 学习
获得产品和技术
作者简介  | |  |
Matthew Leming 于 2002 年加入 IBM。他从 WebSphere Application Server 的版本 5 开始就参与该产品的各个领域的工作,其中包括事务组件和缺省消息传递提供程序。他最近负责与 Adrian Preston 合作开发 WebSphere MQ 消息传递提供程序。 |
 | |  |
Graham Hopkins 于 2000 年加入 IBM,他从事 WebSphere application Server 中的 WebSphere MQ 和缺省消息传递提供程序方面的工作,目前是负责 WebSphere Application Server 和 WebSphere MQ 之间交互的首席测试师。 |
对本文的评价
|