导航

J/XFS 介绍

Posted on 2007-04-18 19:33  pegger  阅读(1705)  评论(0编辑  收藏  举报
在 Java 平台上访问银行硬件

Christoph Czernohous
软件工程师, IBM Deutschland Entwicklung GmbH
2001 年 8 月 02 日

由于越来越多的金融机构将 Java 平台纳入其银行业的解决方案,能够控制用于这些解决方案的硬件(诸如:读卡机、打印机以及ATM)真的很有必要。Java 平台金融服务的扩展(J/XFS)能使从事银行应用程序开发的 Java开发者轻松一些,并且为此项工作提供一种可靠的体系结构。在本系列(共两部分)的第 1 部分,软件工程师 Christoph Czernohous介绍了这种健壮的体系结构,提供了 J/XFS 标准的概述和该体系结构的实现 ― 他对之有突出贡献的 J/XFS for FDI(J/XFS金融设备接口)。请在 讨论论坛和作者以及其他读者交流对本文的心得。

从虚拟机内访问硬件一向是一种挑战。当从虚拟机内访问专门的目标设备(比如:自动柜员机ATM)时,尤其显而易见。我们这些从事银行应用程序开发的开发者发现:通常没有预先确定的方法来开发底层银行硬件的功能。从开发者的角度看,将这样的设备封装起来,使其能够通过一个定义好的接口访问(就象虚拟机本身封装了底层的计算机硬件一样)是很理想的。如果这样,不管安装了什么类型的硬件,这样的设备都作为可选的却熟知的附件回应虚拟机。

Java开发者值得庆幸的是这样的封装不再是空想。J/XFS,Java 平台的一种扩展,提供了一套标准的 Java接口,支持用于银行应用程序的各种输入、输出设备。这样,J/XFS 给应用程序新的类提供了 Java技术的全部能力,即面向对象和独立于硬件制造商以及操作系统厂商。实际上,J/XFS 甚至不局限于特定的通信拓扑结构,我们将在本文的后面部分讨论。

本文(两部分系列的第 1 部分)作为 J/XFS 及其参考实现 ― J/XFS 的金融设备接口( FDI )的介绍。 我将讨论需求、历史以及为J/XFS 定形的设计决策,解释组成内核的不同部件怎样共同工作和介绍 FDI for J/XFS。出于为该系列的第二部分(我们将更多地讨论在J/XFS 框架下开发设备服务)作准备的目的,我将向您展示怎样安装和配置 FDI for J/XFS(从 J/XFS 论坛可免费得到,请参阅 参考资料)。

在第 1 部分结束时,您将懂得怎样安装 J/XFS 以及 FDI for J/XFS 怎样实现这种体系结构。您还将安装和配置软件,它包含完全可操作的演示,有助于您通过实践学习此项技术,为第二部分内容作准备。

J/XFS 体系结构
J/XFS设计师做了一些深刻影响其本质的设计决策。他们所做的基本的决策之一是:在设备上执行的大多数操作将以异步方式执行。如果您发送消息给 J/XFS设备,您所调用的方法立刻返回一个标识号。如图 1 中的序列图表所示,您启动的操作的实际结果将在一段时间后,在一个单独事件里返回报告给您。

图 1. 异步操作
图 1. 异步操作

先于 J/XFS 的另一种银行外围设备标准 ― Windows开放系统体系结构/金融服务的扩展(WOSA/XFS)早已经定义好了。这种标准广为人知,但是确实有一些缺点。例如,因为此标准使用 C编程语言定义其接口,它没有使用基本的面向对象的概念。此外,它被局限在一个操作系统。为了便于已经很熟悉 WOSA/XFS 的开发者学习J/XFS,基本的 J/XFS 设备规范都是基于 WOSA/XFS 的。这种折衷使得 J/XFS规范在某些地方看起来有点不象是面向对象,但是它显然促成了这种体系结构被接受。

J/XFS 的过程中,网络和通信受到了进一步关注。此外,由于 J/XFS 设备是独立于制造商的硬件,可以被分布和使用于网络。网络本身,即它的硬件和协议,对应用程序完全透明。通信层能被完全交换,人们期望的任何网络技术都有实现的可能性。

为了更好地理解这些决策是怎样对 J/XFS 体系结构产生影响的,我们来看一看内核及其基本的组件。

内核内部
J/XFS为带有起支持作用的中间件的传统的客户/服务器环境,即内核。内核是 J/XFS 的核心,提供基本的基础结构和安装 J/XFS 环境要用到的Java 类库。它负责跟踪所有连接的设备以及应用程序和设备之间的消息、事件传递。此外,内核也提供诸如:持久存储或日志、跟踪的支持功能。

因为它由两个独立的 Java API 组成(一个用于应用程序,一个用于硬件设备),所以, J/XFS 内核也作为编程框架。图 2 展示了该框架的组件。

图 2. J/XFS 环境的组件
图 2. J/XFS 环境的组件

J/XFS 的历史
1998年 9 月,来自 DeLaRue,IBM,NCR,Sun Microsystems 和 Wincor Nixdorf的代表,在一起讨论了怎样能将银行设备集成到电子商务环境中。Java平台稳步发展足可以应用于金融应用程序,显然所有与之相关的群体,包括消费者,都能从集成应用程序这一普遍方法中受益。这样,他们成立了 J/XFS论坛 ― 一个由来自于所有五个公司的成员组成的社区(请参阅 参考资料)。J/XFS 论坛的目的是为银行应用程序设计 Java 中间件,定义能被所有参与的公司接受的 API。

半年之后,1999 年 3 月,系统设计和规范准备就绪。为了强调 J/XFS 的重要性,J/XFS 论坛决定发行这种 API,作为官方的开放标准。因此,1999 年 5 月,他们着眼于欧洲标准化体系,建立了 CEN 工作室(请参阅 参考资料)。选择欧洲标准化体系是因为最初的研究始于欧洲。尽管如此,J/XFS 仍是应用于全世界的标准。

1999 年 9 月此规范被认可,自 2000 年 3 月起即可从 J/XFS 论坛 Web 站点免费下载其实现。

自该标准的第一个版本发布以来,CEN 工作室不断改进和扩展这个规范。今年晚些时候,可能出现实现的更新版。更新版将反映近期的改动,包含在规范的第一版中遗漏的设备类型的支持。

标识符
每个使用 J/XFS 的 Java 应用程序都在 J/XFS 客户上运行。因为内核管理连接的 J/XFS 客户的列表,因此必须有识别它们的方法。J/XFS 使用被称为 配置键的标识符来区分多个 J/XFS 客户。 此外,多个 J/XFS 客户能够在一起组成逻辑单元。例如,可以将在一个特定的计算机上的所有 J/XFS 客户放进一个组。您必须将一个 J/XFS 客户正好分配到一个组。这些组的标识符被称为 工作站名。“工作站名+配置键”必须是用来识别 J/XFS 客户的唯一组合。

正如应用程序需要被唯一地识别,必须有方法来区分所配置的设备。J/XFS 对设备采用了与对应用程序一样的方法。 J/XFS中的每一个设备必须刚好连接一个 J/XFS 客户,J/XFS 客户反过来作为 J/XFS客户组的一部分,通过其工作站名进行识别。必须给每个设备分配一个 ID,此 ID 在有同一个工作站名的组内一定是唯一的。ID 被称为 设备名。这样在 J/XFS 环境中,再一次用“工作站名+设备名”识别一个设备。

请注意被分在一组(因为同一工作站名)的 J/XFS客户没有必要在同一物理工作站。组的标识符以工作站名命名是因为这是最适合的目标之一。但是一个组能跨越一个以上的物理计算机。反之亦成立:在一个工作站上可能有多个组。如果听起来让您感到糊涂,只考虑一个 J/XFS 客户组一个工作站名的情况。

应用程序接口
从应用程序角度来看,您并不知道(因为也没有必要知道)任何与之进行通信的硬件的机器特定细节。您所要知道的只是将要使用的设备的 类型。J/XFS 标准为每一种支持的设备定义了一个 Java 接口。目前,J/XFS 标准包括下面几种设备类型的规范:

  • 收据打印机、日志打印机、存折打印机、文档打印机、扫描仪
  • 现金分配器、现金回收器、ATM
  • PIN 小键盘
  • 芯片卡阅读器、磁条卡阅读器
  • 文本输入/输出设备
  • 报警设备
  • 库存单元
  • 支票阅读器和扫描仪
  • 传感器和指示器系统
  • 摄像机

这些接口定义了它们所描述的设备类型的功能。设备实现由内核提供。这些类被称为 设备控件。一个设备控件代表应用程序内的一个设备,作为设备本身的句柄和代理。

将与设备相关的所有消息发送给设备控件,内核关心的是消息有没有到达实际的设备。对这些消息的响应 ― 在设备上执行的操作的结果,将作为事件向您报告。为了接收这种信息,必须注册适当的侦听器对象。

设备接口
在内核的另一端定义了单独的 API 来插入硬件,并且使得内核可以访问它。这个 API完全独立于内核的应用程序接口,因此应用程序开发者没有必要知道关于它存在任何信息。 正如我前面提到的,为每一设备类型定义一个 Java接口。内核使用这个接口来访问设备。这些接口的实现被称之为 设备服务。它们负责对硬件的兼容 J/XFS 的行为进行控制。设备服务与它们控制的硬件紧密结合在一起。因此,如果想在 J/XFS 中使用特定类型的硬件,必须为之提供兼容 J/XFS 的设备服务。

内核为设备服务提供了“纤细”的接口,允许将事件回送给应用程序。

通信层
内核内部可以使用任意一种需要的通信类型。J/XFS 定义了明确的接口,允许通信层完全地交换。新的通信类型通常由 J/XFS 内核开发小组开发并集成到内核中。

作为 J/XFS 应用程序或设备服务开发者,您没有必要知道使用中的实际通信类型。事实上,您可以在部署应用程序之后改变通信层,完成这些不用修改一行应用程序代码或设备服务代码。

当 J/XFS 进行通信时要考虑一种特殊情况:如果不需要或不可能在网络上分布 J/XFS 环境,可以选择在一台 Java 虚拟机上运行任何东西。在这种情况下,不必通过网络发送消息,但应用程序和设备服务必须仍能够彼此通信。

对于这种情况,J/XFS 标准定义了一种特殊的通信类型 local。这种通信类型实际上以它表现出的细微不同的行为来区别于所有其它类型。但是这些仅仅是比较小的差别;可以将这种 local 类型当作是没有网络和在虚拟机内部进行信息交换的通信。

图 3描绘了异步设备在 J/XFS 中的访问。此图表建立在图 1 所示的图表的基础上,添加了些到目前为止所描述不同的组件。

服务器端
J/XFS 是一个客户/服务器系统。由于这个原因,J/XFS 环境中一定要正好有一个 J/XFS 服务器。没有中央服务器 J/XFS 不能工作。这个 J/XFS 的核心组件也是内核的一个部件。J/XFS 服务器要完成三项主要任务:

  • 所有 J/XFS 组件的持久存储
  • J/XFS 环境的动态行为监视
  • 管理任务和系统管理的访问点

配置服务器是持久数据在 J/XFS环境中的首选的位置。它在对象库内为每一个应用程序和设备服务提供虚拟空间。运行时如果需要记住超出应用程序生存周期的信息,应该将其发送到J/XFS 服务器以便持久存储。为了检索存储在该服务器的数据,必须提供唯一的键值(您能够记得的)。 所有的内核配置信息存储在配置服务器中。

当 J/XFS 客户启动时,将在 J/XFS 服务器宣布其可用性。J/XFS 服务器的 动态服务器部件收集此信息。而更重要的是关于可用的设备服务信息。设备服务一旦被成功地初始化和启动,它将使动态服务器知道这一信息,这样应用程序就可以为它请求设备控件且开始使用设备。J/XFS 服务器收集所有的这些信息。

J/XFS 服务器的第三个部件为叫做 监控器的东西。为了配置 J/XFS 环境或在运行时影响其行为,它为管理工具提供了接口。通过开发强大的监控器 API,这些工具具备了一些能力,例如:远程启动和停止设备服务、关闭 J/XFS 客户以及修改配置服务器库中的值。

客户端
在运行时,Java 应用程序代表一个 J/XFS 客户。为了能够访问 J/XFS 的基础结构,J/XFS 应用程序中必须做的第一件事是初始化 设备管理器。设备管理器是 J/XFS 客户应用程序的核心部件。它负责建立 J/XFS 环境以及在运行时管理所有与客户有关的管理任务。

从设备管理器获得 设备控件。将唯一的设备标识符(工作站名+设备名)告诉它,作为回应 ― 假设标识有效以及设备是可用的 ― 将得到设备控件。

如果不知道工作站名和设备名,可以请求设备管理器提供设备列表。获得不同种类设备的列表有多种方法,取决于所需的信息。例如,可以向设备管理器请求所有活动的设备列表、具有应用程序的工作站名的所有设备列表或者所有配置好的设备列表,不管它们是不是活动的。一旦有可用的工作站名和设备名,可以向设备管理器请求设备控件,并且用它开始工作。

每一个 J/XFS 客户还包含一个 日志记录器对象。可以发送所有的日志和跟踪这个对象的信息。侦听器对象可以向日志记录器进行注册,日志记录器发送日志并跟踪日志信息。为了减少实际的信息处理量,可以给日志记录器添加一个过滤器,这样侦听器只接收部分日志并只跟踪所关心的信息。这是一种很灵活的方法,因为可以编写自己的日志侦听器类,该类以您希望的方式处理信息。

实现:FDI for J/XFS
为了能够提供一些现成可用的组件(能够集成到目前的解决方案中),J/XFS 论坛选择实现 J/XFS 内核。这种产品被称为 J/XFS 的金融设备接口(FDI),可以从 J/XFS 论坛 Web 站点免费下载(请参阅 参考资料)。FDI for J/XFS 带有所有定义好的接口和类,它们是您现在开始使用 J/XFS 所需要的。此外,它的类库包含几种工具和支持类,帮助您使用 FDI for J/XFS 进行工作。

这些将在配置和管理过程中提供支持并帮助您了解此产品的工具如下:

  • 基本配置工具(BCT)是一个简单的命令行工具,使您能够完成基本的配置和管理任务。例如,可以将配置信息发送给 J/XFS 服务器或者看一看当前可用的 J/XFS 客户列表。BCT 可以被交互地使用或者可以把BCT 命令列在文件中以便进行批处理。
  • 日志服务器和相应的 日志侦听器可以用来在中央位置收集日志和跟踪来自多个 J/XFS 客户的信息。这些工具用 RMI 在网络上发送数据。
  • 设备服务启动器是没有任何业务逻辑的单独的 J/XFS 应用程序。其唯一的目的是启动 J/XFSI 客户,因此可以远程访问与之相连的设备。
  • Melange demo是一个 J/XFS 应用程序样本,允许在 GUI 中执行所选设备的一些操作。其目的是帮助您熟悉 FDI for J/XFS环境。使用这个工具需要有 Java 基础类库。FDI for J/XFS 提供了几个具有有限功能的设备服务样本,因此您可以操作一遍Melange demo。实际上这些是模拟器,因为它们并不管理真正的硬件。Melange demo和设备服务样本都提供了源代码,但它们决不希望被用作真正的设备服务的模板。

安装 FDI for J/XFS
迄今为止,对于 FDI for J/XFS 还没有自动安装过程或指导安装的工具。您需要手工地进行 FDI for J/XFS 的 1.01版本的安装。为了安装 FDI for J/XFS,需要 Java 虚拟机 1.1.8 或更高的版本。如果您在 Java 2平台上工作,对于该版本的 FDI for J/XFS,必须禁用安全性。100 MHz 工业标准的 PC 对于客户来说已经足够了;服务器需要至少200 MHz。您要在 FDI for J/XFS 的文档中查找准确的最小要求(以及一个测试 FDI for J/XFS所用到过的操作系统和相应的 Java 虚拟机的列表)。请注意这些只是对 FDI for J/XFS 的要求;您必须给它们添加您的应用程序的要求。

在下载了包含 FDI for J/XFS 的 zip 压缩文档之后,执行下面的步骤:

  1. 将zip 压缩文档解压缩到您选择的目录,并阅读 readme.html 文件。该 zip 压缩文档包含 PDF 格式的附加文档和 HTML格式的 API 文档。为了方便,API 文档打包到一个单独的压缩文档 ― jxfsapidoc1.01.zip 中。
  2. 使 Java 虚拟机能够访问 Java 压缩文档。您最可能要做的是通过将压缩文档的文件名添加到系统的 CLASSPATH 环境来完成。在客户机上,压缩文档是 jxfsclient1.01.jar;服务器的压缩文档名是 jxfsserver1.01.jar。
  3. 在服务器系统上创建新的空目录,该目录可以存放所有的持久数据。本例使用 /home/jxfs/repository 目录。

配置 FDI for J/XFS
配置 FDI for J/XFS 有点棘手,因此在进行配置之前请仔细阅读这一段的每一步。

安装客户和服务器

  1. 为每个 J/XFS 客户逻辑组选定一个唯一的工作站名。至少需要一个工作站名。本例使用 developerWorks作为工作站名。
  2. 在所分配的 J/XFS 客户的逻辑组内,为每一个客户选定一个唯一的配置键。本例客户使用配置键 jxfsClient,服务器使用 jxfsServer
  3. 有两个地方要涉及到 TCP/IP 通信:客户和服务器之间以及客户与客户之间。它们中的每一处需要一个没有用到的 TCP/IP 端口号。如果一个TCP/IP 主机上有多个 J/XFS 客户,用于客户到客户通信的 TCP/IP端口号对于每一个客户来说必须是不同的。本例中客户/服务器通信使用端口 2323,J/XFS 客户间的通信使用端口 2424。区分 J/XFS工作站名和 TCP/IP 主机名是很重要的。这两者是完全独立的,当然可以是相同的。
  4. J/XFS 服务器从简短的配置文件读取其配置信息。在 server.cfg 文件里提供了配置信息的骨架。可以在 zip 压缩文档解压缩到的目录中找到该文件。配置信息由键值对组成。编辑该文件,填入前几步建立的信息。
    • workstation_name :指定给 J/XFS 服务器的工作站名。如前面所述,本例使用的是 developerWorks。
    • config_key :J/XFS 服务器的配置键,本例为 jxfsServer。
    • sdm_addparm_1 :用于 J/XFS 服务器和所有 J/XFS 客户之间通信的 TCP/IP 端口,这里是 2323。
    • sdm_addparm_2 :是安装期间为 J/XFS 服务器创建的目录的位置:/home/jxfs/repository。
    • log_file_name :启动 J/XFS 服务器期间,只要发生问题,就会写日志文件。提供服务器可以存放该文件的路径和文件名,比如:/var/log/jxfs/server.log。
  5. 剩下的值保持不变。请注意:在使用反斜杠作为路径分隔符的系统中,反斜杠必须用 \ 表示。
  6. com.jxfs.forum.tools.serverstart.JxfsServer 启动 J/XFS 服务器,并提供文件 server.cfgand 的路径作为其参数。完成了这一步,J/XFS 环境就配置好了并且运行。
  7. 配置一些设备服务样本以供 Melange demo 使用。您可以用包含的 BCT 批处理文件(developerWorks.bct - 请参阅 参考资料)设置客户。在此之后,您必须在文件中替换 所有下面出现的字符串:
    • < device_port > 客户之间通信所选定的 TCP/IP 端口号,此次配置我们使用端口 2424。
    • < hostname > 客户所在的计算机的 TCP/IP 主机名。

配置 BCT
由于 developerWorks.bct 文件由 BCT 命令组成,只有配置过 BCT 才能使用。这又是一个带有键值对的属性文件。

  • workstation_name :指定给 J/XFS 客户的工作站名。如前面所述,本例使用 developerWorks。
  • config_key :BCT 的配置键;您可以将其设置为 BCT
  • sdm_addparm_1mgmt_addparm_1 :用于 J/XFS 服务器和所有 J/XFS 客户之间通信的 TCP/IP 端口。您将使用端口 2323 和 J/XFS 服务器所在计算机的 TCP/IP 主机名。请注意端口和主机名必须由分号隔开。
  • log_file_name :BCT 中 J/XFS 客户启动期间,只要出现问题,就会写日志文件。提供服务器可以存放该文件的路径和文件名,比如:/var/log/jxfs/bct.log。

剩下的值再一次保持不变,请记住在使用反斜杠作为路径分隔符的系统中,反斜杠必须用 \ 表示。

因为 BCT 是系统管理工具,它没有存放在客户的 Java 压缩文档 jxfsclient1.01.jar,而是在服务器压缩文档jxfsserver1.01.jar 中。使 jxfsserver1.01.jar 在 Java 环境中可用,并通过启动 Java 程序 com.jxfs.forum.tools.bct.BCT (以 BCT 批处理文件名作为参数)来启动 BCT,将配置信息发送给 J/XFS 服务器。请注意参数前必须冠以 @ 符号。如果批处理文件叫 developerWorks.bct BCT,您将以 @developerWorks.bct 作为参数提供给 BCT Java 程序。

Melange demo
最后,准备启动演示程序,Melange demo。我们将再一次使用属性文件来安装该程序。这一次骨架文件叫 demo.cfg。对其进行编辑,下面的键要使用恰当的值:

  • workstation_name :指定给 J/XFS 客户的工作站名。本例使用 developerWorks。
  • config_key :J/XFS 客户的配置键;这个示例选用 jxfsClient 作为它的值。
  • sdm_addparm_1 :用于 J/XFS 服务器和所有 J/XFS 客户之间通信的 TCP/IP 端口。这里我们使用端口 2323 和 J/XFS 服务器所在计算机的 TCP/IP 主机名。请注意这两者必须由分号隔开。
  • log_file_name :如前面提到的所有情况,在 J/XFS 客户启动期间,只要发生问题就会将写日志文件。提供服务器可以存放该文件的路径和文件名,比如:/var/log/jxfs/jxfsClient.log。

如果直到这一步您都是按照文章中的步骤进行安装,那么现在您可以自信地启动您的第一个 J/XFS 客户。Melange demo 不是 J/XFS内核的部件,因此存储在一个单独的 Java 压缩文档(jxfsdemo1.01.jar)中。当您使得该压缩文档在 Java环境中可用之后,您可以通过调用 Java 程序 com.jxfs.samples.application.MelangeDemo (将演示配置属性文件作为参数提供给它)来启动 Melange demo。请不要忘记使 Java 虚拟机能够访问 Java 基础类库(在 swingall.jar 文件中包含 Swing )。

图 4 是 Melange demo 的图解。操作这个演示,来感觉一下 J/XFS。

图 4. 带有设备列表的 Melange demo
图 4. 带有设备列表的 Melange demo

总结
这篇文章仅仅作为介绍,不可能涵盖 J/XFS 和 FDI for J/XFS 的各个方面。更多信息包含在放在 FDI for J/XFS 的 zip 压缩文档的文档中。建议您操作演示以及阅读有帮助的文档( 参考资料中介绍的)。该系列的第二部分是 J/XFS 框架下的设备服务开发的实作介绍,那么开始准备吧!




开发来自 Java 平台的银行业设备服务

Christoph Czernohous
IBM Deutschland Entwicklung GmbH
2001 年 9 月 12 日

软件工程师 Christoph Czernohous 继续介绍 J/XFS,它是将银行业的硬件集成到 Java平台的国际标准。使特定的硬件能够在 J/XFS 中可用,这意味着要开发组件或设备服务,组件和设备服务用于对 J/XFS系统的其它部分隐藏外围设备对平台的依赖性。请继续跟随 Christoph 进入为银行业硬件产品提供 J/XFS 支持的必要步骤。您可以在 讨论论坛与作者和其他读者分享您对这篇文章的想法。

正如我在两部分系列的 第一部分所讨论的,Java 平台金融服务的扩展(J/XFS)是一个国际标准,它可用于为表示一块银行业硬件的众多组件定义一个清楚的接口。这些组件被称为 设备服务,并可以插入 J/XFS 系统。以 J/XFS 内核表示的 J/XFS 环境将设备服务作为独立的、内部可变的部分来对待。

在本文中,您将学到在 J/XFS 下开发银行业的设备服务的关键部分。到讨论结束时,您将会理解:

  • 在 J/XFS 下开发设备服务的基本概念和要求
  • 参考实现(面向 J/XFS 的金融设备接口)软件包和文档是如何安排的
  • 在开发来自 Java 平台的设备服务时,FDI for J/XFS 可以如何为您提供支持

如果您还没有看过这个系列的第一篇文章,我建议您在开始读本文前先去读一下第一篇文章。

开发设备服务:基本概念
J/XFS中的设备服务是控制特定的硬件设备的 Java 对象。应用程序不是直接的将消息发送到设备服务对象。取而代之,它们将操作请求消息发送到 J/XFS内核,内核确保消息依次到达目的地。从图 1 中您可以看到,通常都是由内核来调用设备服务对象上的方法的。

图 1. J/XFS 设备服务消息流:从应用程序到硬件
J/XFS 设备服务消息流:从应用程序到硬件

响应发送回应用程序的方式也是一样的。设备服务对象从不把消息直接发送给应用程序。取而代之的是设备服务对象将消息发送给内核,然后由内核将消息发送给适当的接收器。图 2 说明了设备服务是如何向应用程序报告硬件已经改变了状态的。

图 2. J/XFS 设备服务消息流:从硬件到应用程序
J/XFS 设备服务消息流:从硬件到应用程序

这个系统可以很好的服务于 J/XFS 设备服务开发者。因为通常设备服务对象都是与 J/XFS 内核通信的,您所要做的全部事情就是遵照一些基本概念并实现恰当的设备服务接口。在下面的几节中,我将概述在 J/XFS 下开发设备服务时所必须理解和遵照的基本概念。

J/XFS 设备服务接口
J/XFS接口由两部分构成。第一部分定义了所有的设备服务共有的基本行为;第 2 部分是一个特定于每种类型的设备服务的 Java接口的集合。每个设备服务都根据类型来分组的,并且已经为每种类型的设备服务定义好了一个接口集合。在每个集合中都有一个或多个特定于每个设备服务的接口。设备服务仅实现那些符合它们的规范的接口。例如,一个用于 ATM 的设备服务不会去实现存折打印机的接口,因为这两个服务没有被分组在同一类型中。

J/XFS 设备服务封装了特定设备逻辑和行为,实现方法是对 J/XFS 环境隐藏所有的设备特性,仅使其可见由 J/XFS 标准定义的操作。

回调注册和反注册
应用程序通过向 J/XFS内核发送相应的消息来表明它们愿意与某个设备服务通信。内核通过注册一个带有设备服务对象的回调对象来对这个请求做出响应。设备服务为每一个回调对象分配一个唯一的标识数字。然后内核为所有来自该应用程序的请求都添加上这个标识(ID)。该标识数字被称为 控制 ID;每个设备服务都有唯一的控制 ID。

进来的操作请求消息(消息请求您的设备服务器执行一个操作)就是用这个 ID 来区分的。这要求您记住控制 ID 和事件回调对象间的关联。

这些回调对象是设备服务对象所通信的 J/XFS 内核的一部分。它们的唯一目的就是使您能发送事件来报告当前所执行的操作的进展和结果。一旦应用程序不再需要您的设备服务,它通知 J/XFS 内核反注册它的回调对象。

操作的执行和取消
几乎所有的在 J/XFS 设备服务上执行的操作都是以异步的方式执行的。当您的设备服务接收到需要在该设备上执行某一操作的请求时,必须接受该请求,并为其分配一个唯一的标识数字。该 ID 数字(被称为 标识 ID)然后被发送到请求者,所请求的操作在一个单独的线程中被执行。

将控制 ID 和标识 ID 区分开是很重要的。标识 ID 唯一的命名了应用程序在硬件上执行一个操作的单一请求。例如,如果一个应用程序需要在打印设备上打印一些信息并把打印出的那张纸吐出来,那么它需要通过内核向设备服务发送两个请求消息,一个用于打印,一个用于吐纸。每个请求都通过设备服务分配给它的标识 ID 来区分。相反,控制 ID 将唯一的命名产生请求的应用程序。

一个操作一结束,就会通过发送一个操作完成事件来将结果报告回来,操作完成事件包含操作结果和以前分配的ID。如果设备服务在忙于执行前面接收到的操作请求时又收到了多个操作请求,每个请求都被放在队列中并且会按照到达的顺序被执行。这条规则的极少的特例在J/XFS 规范中有清楚的描述(请参阅 参考资料)。

如果操作请求被取消,请求的应用程序将向 J/XFS 内核发送一个请求来取消这个操作。然后内核向设备服务传送包含取消请求和被取消的操作的标识 ID的消息。设备服务必须有一个机制,这个机制可以尽量的停止执行操作并把设备设为操作开始前的状态,尽管这并不总是可以实现的。

状态管理
设备服务在运行时会呈现不同的状态。 大多数状态间的转换在相应的事件中会被报告给单独的或是所有的回调对象。在任何时候 J/XFS 内核都可以向设备服务发送消息请求它当前的状态。

打开和关闭设备服务
在应用程序建立了它自身、J/XFS 和设备服务间的通信基础架构后,应用程序就已经准备好与设备服务一起工作了。但在它可以请求任何相关设备的操作之前,它必须通过请求内核打开设备服务的方式来正式的表达它要这样做的意图。在这一请求中内嵌了唯一的控制ID。内核向设备服务发送一个请求为了操作而打开的消息。如果连接的硬件是可操作的,就通过发送一个相应的 操作完成事件来回答该请求。在这一点,设备服务对象的状态改变了;现在它“打开”来接收相关设备的操作请求。

应用程序一完成与设备服务的工作,并且在它请求内核反注册它的回调对象之前,它必须请求内核发送一个消息到设备服务,该消息包含为那个控制 ID 正式关闭设备服务的请求。此后,设备服务就不能再接受任何其它的关于该控制 ID 的相关设备的请求消息。

排它的访问请求
如你到目前为止所看到的,很多应用程序都可以请求内核为它们注册回调对象。操作请求可以以任何可能的顺序到达设备服务。多数情况下,按照接收的顺序来执行操作请求。

但有时候,一个应用程序必须确保它的请求在被执行时不受其它应用程序的干扰。在这种情况下,应用程序将通过 J/XFS内核向设备服务发送一个要求排它访问的请求。设备服务必须有一种机制来管理来自内核的排它访问的请求。它必须能够确保在给定的一段时间中仅有一个以控制ID 来标识的应用程序被授权了排它访问的权限。一旦设备服务成功的将排它访问和控制 ID 关联起来,仅有控制 ID所标识的操作请求消息可以被执行。所有的其它请求都被放在队列中。

在请求排它访问的任务完成后,内核代表应用程序发送一个请求除去排它访问状态的消息。

纯 Java 代码与 JNI 相对
Java 平台金融服务的扩展,如它的名字所表达的,J/XFS 扩展了基于 Java 的系统的性能。但是,当为 Java 规范所没有包含的附加硬件和特性提供支持时,你迟早会被迫放弃虚拟机的。

非常可能的是 Java 本地接口(Java NativeInterface,JNI)将在这一点上步入舞台。尤其是当您需要快速的产生一个设备服务时,您也许会倾向于使用“包装器(wrapper)”方法 ―― 比如说围绕面向某一操作系统的现存的设备驱动开发设备服务。这种方法就使您不必开发驱动了。另一方面,即使您为了保持高可移植性而在 Java方面开发了大多数的附加代码,但还是有某一比例的部分必须移植到其他的支持Java 技术的平台上,并且应该可以运行使用设备服务的 J/XFS应用程序。另外,使用 JNI 您就要失去一些 Java 平台提供的优点。 但是,当然,存在着由于成本、时间或技术的限制而只能用 JNI方法的情况。

从 Java 开发者的观点来看,专门的用 Java 语言一定是开发 J/XFS设备服务的受欢迎的方法。幸运的是在大多数情况下这是可能的,因为许多现在所用的银行业设备都与标准的串行或并行 PC 接口连接。您可以直接从Java 虚拟机内部使用这些接口。通过使用这种方式,就保留了 Java的所有的优点,尤其是可移植性。单是这一事实就值得付出将一些旧的代码移植到 Java 平台的努力了。

设备服务 API
既然已经对在 J/XFS 下开发设备服务的基本要求有了些认识,我们再来熟悉一下 API 规范。这一节 首先来关注一下 API 的实用编程技巧。所有的说明指的是标准版本 1.0 和它所伴有的内核实现。在 FDI for J/XFS 这节中有对软件包层次结构的解释。

状态管理
如我们前面所讨论的,设备服务对象在它的整个生命周期中呈现出不同的状态。所有可能的状态在所谓的状态类中都有规范进行定义。

JxfsStatus 类将每个设备服务可能呈现的布尔状态也归组进来。状态如下:

  • 打开(Open):设备已经为应用程序打开。
  • 声明(Claimed):对此设备服务对象的排它访问已经授权给一个应用程序。
  • 声明暂挂(Claim pending):至少有一个应用程序请求对设备服务对象进行排它访问,但排它访问还没有被授权。
  • 忙(Busy):设备服务对象当前正在处理一个操作。其后的操作请求将被放在队列中。
  • 硬件错误(Hardware error):设备服务正在控制的硬件指出出现了一个只有服务工作人员才可以修复的错误。
  • 用户行为错误(User action error):设备服务正在控制的硬件指出出现了一个可以由系统管理员来解决的错误。
  • 工作中(Working):设备服务为应用程序而打开了,并且没有出现错误。
  • 节能(Power save):硬件处于低能量消耗状态(less-power-consuming)时就要恢复可用性。

您需要注意设备服务对象所控制的硬件的情况(硬件所提供的所有信息)。在任何时间都必须可以从设备服务对象得到状态信息。大多数状态是彼此独立的,但也存在一些依赖。例如,设备服务对象一定要在被授权排它访问之前开放。状态间相互依赖以至于在 JxfsStatus 实例中的信息总是前后一致的,为了这些状态就必须使用某些种类的同步。

一些设备类型规范定义了 JxfsStatus 的子类来包入甚至更多的状态信息。例如,打印机设备的规范定义了 JxfsStatus 的子类: JxfsPtrStatus 类的子类,它可以提供额外的关于打印机调色剂和供纸单元的状态信息。

一些设备规范所使用的有两个更普遍的状态类: JxfsMediaStatus 收集了硬件单元在处理的介质时可能呈现的状态。例如,在打印机中,介质将是“纸”,纸张供应单元可能呈现的一种状态是“卡纸”。另一个类是 JxfsThresholdStatus ,用于监测可测量单元的级别。例如,在打印机中的供纸情况可以是“满”、“高”、“低”或者“空”。请参见 J/XFS 规范以对状态管理类有更多的了解。

事件
事件是实现设备服务发送信息给应用程序从而向 J/XFS 内核传递信息的唯一途径,这样,就很有必要理解事件是怎样工作的。J/XFS 把事件分为三类: 操作完成事件中间事件状态事件。这些分别表示为 OperationCompleteEvent 类、 IntermediateEvent 类和  StatusEvent 类。

所有的事件为 J/XFS 内核标识事件源(设备服务对象)。这一引用必须作为第一个参数给予所有的事件类型。J/XFS 设备服务的每个异步的操作导致一个 操作完成事件,该事件报告操作的结果。一些特殊设备的操作使用操作完成事件的子类,但不幸的是大多数的设备规范的设计者并没有利用它们。规范为每个操作定义了表示为整数常量的可能结果。另外,为每个操作定义了表示为整数常量的一个 操作标识,以免应用程序记不起它所调用的操作。

中间事件在操作执行时报告操作的进展,其报告的方式与操作完成事件报告结果的方式相同。象上面描述的,当设备服务呈现一个新的状态时, 状态事件就会被发送。不是所有的状态改变都作为状态事件而被报告。设备服务的新状态是用一个整数常量来描述的。例如,如果一个打印机没有纸了,这一事实是通过状态事件来告之应用程序的。

异常
异常机制是 J/XFS 的一个薄弱点,因为仅有一种异常类型: JxfsException 。异常被抛出的原因不是由于它的类型定义部分,而是用一个在接口 JxfsConst 中定义的整数常量来表示的。清单 1 说明了一个所请求的操作不能被支持时被抛出的异常。

清单 1. JxfsException

/* ... */
throw new JxfsException(JxfsConst.JXFS_E_NOT_SUPPORTED);
/* ... */

基本的服务操作
所有的设备服务都要求支持一个主要的接口: IJxfsBaseService 。它声明了所有类型的设备服务共同的所有的方法。在接下来的几节中我们将来研究每个基本的服务方法。

初始化消息
当 J/XFS 内核启动设备服务时,J/XFS 向设备服务发送一个初始化消息,该消息包含了一个 JxfsLocalDeviceInformation类型的对象。这个对象携带着关于设备服务和它所附着的 J/XFS 客户机的一般信息。它为设备服务提供对在 J/XFS服务器上的虚拟空间的访问,这一点与那些信息至少是一样重要的。任何持久的数据都可以存储在 J/XFS服务器上,这就提供了一个存储配置信息的好地方。 初始化消息一到,设备服务就第一次与真正的硬件设备联系。

设备关闭在 J/XFS 客户机关闭过程中,J/XFS 内核向所有的设备服务发送一个关闭消息,如清单 2 所示。这是清理也可能是关闭硬件的好时机。

清单 2. 设备关闭消息

public void initialize(JxfsLocalDeviceInformation deviceInformation)
throws JxfsException

public void shutdown() throws JxfsException

回调对象和控制 ID
J/XFS 内核向设备服务发送一个包含 IJxfsEventNotification 类型的回调对象的消息。设备服务用这个回调对象来向内核发回事件消息。为每个需要与设备服务交互的应用程序发送这种类型的对象。如清单 3 所示,为对象分配一个控制 ID 并返回该控制 ID。

清单 3. 分配一个控制 ID

public int registerControl(String deviceType, IJxfsEventNotification
callback) throws JxfsException
public int deregisterControl(int controlID) throws JxfsException

一旦内核除去了回调对象,就不能再用该回调对象了。

参数 deviceType
参数 deviceType 包含了设备的类型(假使设备服务支持不止一种的类型),但这是高级的设备服务开发,所以这里我们就不深入了。(详见规范)

“打开(open)” 消息
J/XFS 内核发送的消息 open 通知设备服务:很可能操作请求将在给定的控制 ID 后面传入。 参数 controlID 一定要是在一个 IJxfsEventNotification 的实例的 registerControl 方法中分配的一个有效的控制 ID,从而设备服务可以将操作结果报告回来。清单 4 给出了方法的用法:必须在设备服务中实现它以便接收来自内核的 open 消息。

清单 4. 内核为进来的请求准备了设备服务。

public int open(int controlID) throws JxfsException

“关闭(close)” 消息
在内核发送 deregisterControl 到设备服务前(因为 open 请求的一个 IJxfsEventNotification 实例已经被成功地处理了),内核必须发送一个 close 消息以表明没有需要那个控制 ID 的操作请求了,如清单 5 所示。

清单 5. 内核表示不再需要设备服务。

public int close(int controlID) throws JxfsException

方法的声明(claim)和发布(release)
为了获得或返回对设备服务的排它访问, claimrelease 消息被发送到设备服务。 这些方法是少数的在 J/XFS 中不遵守异步操作的规则的方法中的两个方法。直到排它访问被成功的授权或是在参数 timeout 给定的时间里返回了,方法的调用才返回值,如清单 6 所示。

清单 6. 声明和发布排它访问

public boolean claim(int timeout, int controlID) throws JxfsException
public boolean release(int timeout, int controlID) throws JxfsException

当然,排它访问必须在可被返回前授权,并且消息 open 必须在一个 claim 请求前被发送到设备服务而且被成功的处理了。

取消(cancel)请求
内核发送消息 cancel 到设备服务(如果操作是以 identificationID 来标识的话),由回调控制根据 controlID 来启动的操作就要被停止。如果可能的话,设备服务将把硬件置回操作开始之前的状态。取消请求的控制 ID 必须与要取消的操作的控制 ID 相同。没有标识 ID 分配给 cancel 请求,这就意味着 cancel 请求是不能被取消的(这有些不可思议吧)。清单 7 表示了一个取消(cancel)请求。

清单 7. 一个取消(cancel)请求

public void cancel(int identificationID, int controlID) throws JxfsException

getStatus 操作
getStatus 操作是非常重要的,因为它把设备的当前状态通知 J/XFS 系统中所有相关的对象。如清单 8 所示,方法返回一个 JxfsStatus 的实例,因此这个方法是在 J/XFS 设备服务中异步处理规则的另一个例外。

清单 8. getStatus 操作

public JxfsStatus getStatus(int controlID) throws JxfsException

关于该方法您需要理解两点。如前面所概述的, JxfsStatus 和它的子类包含关于一些不同状态的信息。 第一点要求是相互依赖的状态必须一直前后一致。例如,状态“claimed”依赖状态“open”:设备服务必须在被声明前打开。当收集状态信息供给  JxfsStatus  的一个新的实例时,必须同步的访问那些状态。

第二点与 JxfsStatus 类的设计有关。 JxfsStatus 的实例是值对象,这意味着值对象的唯一作用是携带不提供任何逻辑的信息。这些对象的内容可以被任何其他的对其引用的对象更改。结果,设备服务必须为 getStatus 方法的每一个调用返回一个新的 JxfsStatus 实例,从而确保设备服务拥有一个对对象的引用,而其他对象都不能更改它的内容。

getStatus 操作的简单易懂的实现与清单 9 很相似。假定设备服务有一个内部的监视对象来同步访问方法 getStateMonitor() 返回的所有的状态信息。每个状态可以被相应的方法(例如, isClosed() )查询。实现必须确保当任何对象锁定了由 getStateMonitor() 返回的对象时,状态信息不可改变。所以,您必须检查设备服务是处于“打开”状态,并且如果不是的话就抛出定义的异常。请阅读关于每个方法的 J/XFS 规范来找出您必须检查什么条件。然后,创建一个新的 JxfsStatus 实例,设置所有的状态信息,并返回给访问者。

清单 9. getStatus 的实现

public JxfsStatus getStatus(int controlID) throws JxfsException
{
synchronized (getStateMonitor())
{
if (isClosed())
throw new JxfsException(JxfsConst.JXFS_E_CLOSED,
"The device service is in state 'closed'.");
final JxfsStatus state = new JxfsStatus();
state.setBusy(isBusy());
state.setClaimed(isClaimed());
state.setClaimPending(isClaimPending());
state.setHardwareError(isHardwareError());
state.setOpen(isOpen());
state.setPowerSave(isPowerSave());
state.setUserActionError(isUserActionError());
return state;
}
}

设备服务信息
设备服务必须提供一些自身的版本信息和所控制硬件的描述。 getDeviceServiceVersion 操作在 JxfsVersion 的一个实例中提供当前安装的设备服务的版本。

清单 10 中所示的其他两个方法返回了与设备服务相连的硬件的类型和硬件的更详尽的描述。如果设备服务支持多种机器(例如相同类型的不同型号),这里设备服务应该给出实际上的配置。

清单 10. 获得关于设备服务的信息的三个操作

public JxfsVersion getDeviceServiceVersion(int controlID) throws JxfsException
public String getPhysicalDeviceName(int controlID) throws JxfsException
public String getPhysicalDeviceDescription(int controlID) throws JxfsException

固件管理支持
J/XFS 提供有限的固件管理支持。在 getDeviceFirmwareVersion 操作中,如清单 11 所示,设备服务返回 JxfsVersion 的一个实例来说明当前安装的硬件的版本。

另外,可以在 J/XFS 服务器上永久的存储固件。 getRepositoryFirmwareVersion 的结果是 J/XFS 服务器的对象库中的可用固件的版本。设备服务可以通过发送消息 getValueForKeysetValueForKeyJxfsLocalDeviceInformation 实例来读出和写入 J/XFS 服务器,该实例是设备服务在 initialize 方法中接收的。

如果设备服务不支持固件管理,设备服务一定要抛出 JxfsException 异常,错误代码是 JxfsConst.JXFS_E_NOT_SUPPORTED

getFirmwareStatus 操作比较这两个版本并且以一个整数常量来报告哪一个比较新和硬件的固件的更新是否可能使用 J/XFS 服务器上的那个版本。如果设备服务不支持固件的更新,设备服务必须返回 JxfsConst.NO_SUPPORT

如果选择为设备服务的用户提供固件更新的方便,实际的更新就在 updateFirmware 方法中处理。注意尽管这个操作不返回标识 ID ,它仍然是异步的。因为 J/XFS 服务器可被 J/XFS 环境中的许多对象使用,所以需要清楚的用文档说明为了固件管理在 J/XFS 服务器上使用了哪些密钥,以使数据不会被意外的重写。

清单 11 表示了 J/XFS 中与固件管理相关的四个方法。如果想让应用程序在与设备服务的结合体中使用 J/XFS 固件管理特性,就需要实现这些方法。

清单 11. 与固件管理相关的方法

public JxfsVersion getDeviceFirmwareVersion(int controlID) throws JxfsException
public JxfsVersion getRepositoryFirmwareVersion(int controlID) throws
JxfsException
public int getFirmwareStatus(int controlID) throws JxfsException
public boolean updateFirmware(int controlID) throws JxfsException

节能模式
如果硬件支持操作方式消耗较少的能量,那么通过在 isPowerSaveModeSupported 方法中返回 true 来表明这一点。处于这种方式是设备服务在 JxfsStatus 实例中报告的状态之一,象前面所说的,状态可以通过发送 getStatus 消息到设备服务来获得。

为了把硬件置回完全操作的方式,J/XFS 内核发送 wakeUpFromPowerSave 消息到设备服务,如清单 12 所示。

清单 12. 设置节能模式

public boolean isPowerSaveModeSupported(int controlID) throws JxfsException
public int wakeUpFromPowerSave(int controlID) throws JxfsException

处理一个丢失的连接
假使与一个回调对象的连接由于某种原因而丢失了,J/XFS 内核就发送给设备服务一个包含回调对象的控制 ID的消息。一收到那个消息,设备服务必须能够除去对给定的控制 ID 的排它访问,把对于那个 ID 的状态设为“关闭”,并且反注册回调对象。清单13 表示了连接失败消息。

清单 13. 连接失败消息

public void connectionFailure(int controlID)

directIO 操作
directIO() 操作是 IJxfsBaseService 接口中唯一使用硬件的操作功能的操作。但与其他的在特定设备 J/XFS 接口中定义的操作相比它也是一个例外。如果硬件(您正为其开发设备服务)提供没有被包含在 J/XFS 标准中的功能,您可以使用这个操作包含被请求的信息。

从选择一个比 JxfsConst.JXFSDIRECTIO_OFFSET 大的整数值开始来标识特定硬件的功能。设备服务在硬件上执行必要步骤所需的所有信息一定要隐藏在一个 JxfsType 类型的对象中。子类 JxfsType 创建一个新的类来包含设备服务所需的所有信息。

理想情况,您决不需要支持 directIO 。因为使用 directIO 的代码还没有被标准化,所以如果要使用该代码就要损失可移植性。在多数情况下,您应该通过抛出 JxfsException 异常(错误代码 JxfsConst.JXFS_E_NOT_SUPPORTED )来实现 directIO ,如清单 14 所示。

清单 14.directIO 的典型实现

public int directIO(int command, JxfsType serializable, int
controlID) throws JxfsException
{
throw new JxfsException(JxfsConst.JXFS_E_NOT_SUPPORTED);
}
]

特定设备操作
独立的 Java 接口用于声明 J/XFS 所支持的不同的硬件类型的功能。每种类型的硬件至少有一个接口。如果您想为给定的硬件类型建一个新的设备服务,您只需在实现上面所概述的 IJxfsBaseService 时同时实现针对于那种类型的硬件的适当的接口即可。

如果您不想支持在接口定义中所描述的某一特殊函数,在多数情况下,您可以通过抛出 JxfsException 异常(错误代码是 JxfsConst.JXFS_E_NOT_SUPPORTED )来表明这一点。

例如,描述打印机功能的接口之一是 IJxfsPrinterService 。它与其它的接口都包含的操作之一是用于复位打印机硬件的 resetPrinter 操作。如果您要写一个提供可复位硬件的打印机设备服务,那么您就要写一个新的类来实现 IJxfsBaseServiceIJxfsPrinterService ,并把复位硬件的必要代码放在 resetPrinter 方法中。

FDI for J/XFS
面向 J/XFS 的金融设备接口是 J/XFS 内核的实现。您可以从 J/XFS 论坛主页上免费下载该接口(请参阅 参考资料)。除了实现标准的规范以外,FDI for J/XFS 还包括许多旨在方便在 J/XFS 环境中的软件开发的有用的条款。我们将在接下来的几节中研究这份文档。

文档
在包含 FDI for J/XFS 的 ZIP 压缩文档中,您将看到描述框架的信息的五种来源:

  • 对于开发者来说也许最重要的进入点是 HTML 格式的完整的 API 文档。标准中所没有涵盖的每个细节在该文档中都可以找到。
  • 对于想要成为设备服务开发者的人来说第二个最重要的文档是 《Device Service Programming Guide》。它包含了几乎与本文相同的主题,然而本文中还提供了一些那份文档中所没有的信息。
  • 如果您想熟悉 FDI for J/XFS 的全部概念,请参阅 《System Overview》。当然,也许您想看看 这个系列的第一篇文章
  • FDI for J/XFS 的安装和配置在 《Administration Guide》中介绍。
  • 《Application Programming Guide》没有包含很多的用于开发设备服务的有用的信息。

数据包概述
与设备服务开发相关的数据包层次结构如下:

  • com.jxfs.control.cdr
  • com.jxfs.control.msd
  • com.jxfs.control.pin
  • com.jxfs.control.ptr
  • com.jxfs.control.tio

设备操作所需的所有的类都在与这些数据包一起的 J/XFS 标准中定义。下面的是一些附加的数据包:

  • com.jxfs.events 数据包包含了所有的 J/XFS 事件类,当然差劲的 JxfsException 类也在其中。
  • com.jxfs.forum.support 数据包包含用于提供方便的额外的辅助类。
  • com.jxfs.general 数据包将 J/XFS 的核心的类和接口分组。包括
    • JxfsConst
    • JxfsLocalDeviceInformation
    • JxfsMediaStatus
    • JxfsStatus
    • JxfsThresholdStatus
    • JxfsType
    • JxfsVersion
  • com.jxfs.service 数据包很重要。它包含 IJxfsBaseService 接口和所有的设备服务接口。
  • 下面的数据包为每种 J/XFS 所支持的设备类型包含一个抽象的超类:
    • com.jxfs.service.alm
    • com.jxfs.service.cdr
    • com.jxfs.service.msd
    • com.jxfs.service.pin
    • com.jxfs.service.ptr
    • com.jxfs.service.tio

日志和跟踪支持
J/XFS 定义了内置的日志和跟踪支持。当涉及到跟踪代码,尤其是一旦对于产品时,这就会很方便。发送所有的日志和跟踪信息给核心的 JxfsLogger 类型的对象,通过调用类的 getReference 方法来获得对对象的引用。

日志和跟踪入口是用唯一的 origin字符串来标识的。选择日志和跟踪信息所需的所有 origin(确信您可以在生成的日志和跟踪文件中容易的识别出每个 origin)。在可以使用日志和跟踪工具前,必须通过发送 registerModule 消息给 JxfsLogger 对象,让该对象知道 origin 的存在。在停止对一个给定的 origin 进行日志和跟踪前,不要忘记用 deregisterModule 消息反注册。

可以用不同的级别来按优先顺序处理跟踪入口。100 以下的整数值是为 J/XFS 内核保留的,但可以用所有的比 100 大的值。

日志信息随 writeErrorLog 消息被发送到日志记录器(logger)。需要为每个日志入口提供日志模块的 origin 字符串、错误代码以及扩展的错误代码。除了日志字符串外,您还可以提供关于如何解决通到日志入口的问题的附加信息和一个可以检索到附加信息的 URL。

writeLog 消息发送跟踪信息给日志记录器(logger)。因为跟踪应该是被广泛使用的,但是通常在运行时是禁用的,所以跟踪字符串的准备在计算能力方面就很昂贵了。节约计算能力还有找出对 origin 和级别的跟踪是否已被激活的一种方式是发送 isLogActive 消息给 J/XFS 日志记录器(logger)对象。

日志和跟踪消息都包含对入口生成的对象的一个引用。对于设备服务,这是个对设备服务对象的引用。清单 15 说明了 J/XFS 的日志性能是如何被使用的。

清单 15. 设备服务类的实现

// ...
final String origin = "developerWorksDeviceService";

JxfsLogger.getReference().registerModule(origin,
"J/XFS device service for IBM developerWorks.");

// ...

// log
JxfsLogger.getReference().writeErrorLog(this, origin, 0 /* error code */,
0 /* extended error code */,
"This is an error log entry.",
"Hint to solve the problem.",
"Find more information at http://www.ibm.com/java.");

// ...

// trace
if (JxfsLogger.getReference().isLogActive(origin, 101))
JxfsLogger.getReference().writeLog(this, origin, 101, "J/XFS
trace entry.");

// ...

JxfsLogger.getReference().deregisterModule(origin);

// ...

接口和抽象类
J/XFS 在标准的规范文档中定义了设备接口。但对于现实的编程需要可以在代码中使用的 Java 类文件。FDI for J/XFS 产生必要的类。

除接口外,FDI for J/XFS 为 J/XFS详细说明的每种设备类型提供抽象超类。您最好把抽象类建立适当的子类,从而适应设备服务的实现。这可以确保如果一个设备规范被扩展了,那么相应的方法会被包含进内核的一个新版本中。方法然后就可以在那些类中以这样的方式来实现:它们仅抛出 JxfsException 异常,出错代码是 JXFS_E_NOT_SUPPORTED

把根据旧的规范开发的抽象类上建立子类的设备服务继承了附加的方法而且继续与新版本的内核一起工作。对新性能的支持可以通过重写继承方法简便的加到设备服务上。

清单 16,作为一个示例说明了用于日志打印机的设备服务类。这个类用了抽象超类 com.jxfs.service.ptr.AJxfsJournalPrinterService

清单 16. 设备服务类的实现

import com.jxfs.service.*;
import com.jxfs.service.ptr.*;
// ... import any packages needed
public class DeveloperWorksJournalPrinter extends AJxfsJournalPrinterService
implements IJxfsBaseService, IJxfsPrinterService
{
// implementation of the device service ...
}

支持类
FDI for J/XFS 为设备服务的开发提供为数不多的类。这些类分组在数据包 com.jxfs.forum.support 中。

最重要的支持类是 QueueControl 。该类定义了一个队列,你可以使用该队列来实现设备服务中的操作请求的异步执行。思路是把所有的代码为一个设备操作而分解成一个独立的类。这样的类实现 IJxfsServiceJob 接口,因为这些“作业”对象可被加到队列控制对象。队列控制对象可被用在主动方式或被动方式中。不同之处是主动方式中队列控制使用它自己的控制线程来连续的执行队列中的作业,但在被动方式中您需自己创建一个控制线程并发送 getNextJob 消息给队列控制对象,从而获得并执行队列中的下一个作业。

支持数据包还包括操作请求的实现,操作请求请求的操作有 opencloseclaimrelease ,它们分别在 OpenJob 类、 CloseJob 类、 ClaimJob 类和 ReleaseJob 类中。请阅读有关这些类的文档以了解如何使用它们。

另一个有用的类: IDFactory 。这种类型的对象产生数字 ID,这些数字 ID 有些用于内核在设备服务注册时区分回调对象(控制 ID),另一些用于标识操作请求(标识 ID)。

总结
我希望这个系列能够作为 J/XFS 平台和它的参考实现(即 FDI forJ/XFS)的一个好的介绍。通常,一旦您理解了设备服务开发中的基本概念,实现它们就不太困难了。借助这个系列,我的目标是准备和鼓励您开发自己的J/XFS 设备服务,从而满足来自银行业应用供应商的要求并扩展 J/XFS 和 Java 平台的使用。如果您有关于 J/XFS的其他问题和关注,我鼓励您把它们发布在与本系列有关的 讨论论坛上。

参考资料


河南恒友科贸有限公司 
电话 :0371-53733453    传真:0371-65388972
地址:郑州市郑花路8号 E-mail:hengyousoft@QQ.com