服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

如何避免microsoft非标准javasdk的潜在危险


  ─ ─microsoft在其实现的java 1.1关键类
库中所增加或省略的方法、类和变量

--------------------------------------------------------------------------------

摘 要sun 在 宣 布 其 控 诉microsoft 违 反java 兼 容 性 问 题 协 议 的 起 诉 中 提 出, 对java 关 键 类 库 的 修 改 是 错 误 的。 在 本 文 中,javaworld 投 稿 人、java 开 发 者john zukowsk 对microsoft 新 的sdk 中 到 底 增 加 和 省 略 了 那 些 类、 方 法 和 变 量 做 了 简 明、 全 面 的 总 结。 本 文 提 供 了sun 和 其 他 公 司 仅 仅 暗 示 的、 在microsoft java sdk 中 发 现 的 修 改 的 全 面 列 表, 以 及 每 个 修 改 的 含 义 和 开 发 者 如 何 定 位 任 一 改 变/ 增 加/ 省 略。 总 之, 本 文 说 明 了 用microsoft 产 品 创 建 真 正 的" 编 写 一 次, 随 处 运 行" 的 应 用 和 创 建 在microsoft internet explorer 4.0 上 运 行 的 程 序 时 所 必 须 知 道 的。

microsoft internet explorer 4.0 和2.0 版 的java sdk 均 已 推 出。 根 据microsoft win32 java 虚 拟 机 的 发 布 注 释,ie 4.0 与 新 的sdk 中 的java 虚 拟 机 是 相 同 的。 将sdk 中 的java 类 文 件 与sun 的java sdk 1.1.4 release 中 的 文 件 比 较, 就 会 明 白 为 什 么sun javasoft 部 的 总 裁alan baratz 说"microsoft 欺 骗 性 地 修 改 了 关 键 类, 并 加 入 到 其sdk 中" 参 见10 月 份 新 闻。

我 分 析 了 类, 遇 到 了 七 个 方 面 的 问 题。 如 果 要 用microsoft java sdk 开 发 在 其 他java 1.1 认 证 的 环 境 中 可 以 运 行 的 应 用, 应 该 特 别 注 意 这 些 问 题, 它 们 是:

1. 新 类
2. 新 方 法
3. 新 变 量
4. 更 改 的 接 口
5.com.ms 包
6. 省 略 的 方 法
7. 动 作 差 别

baratz 在sun 宣 布 其 起 诉 时 用" 欺 骗" 一 词 是 因 为sdk 中 所 带 的 关 于java 类 的 文 档 没 有 提 到 这 些 修 改。 要 发 现 它 们, 必 须 用sdk 所 带 的classvue 工 具 或 者 人 工 地 读 源 代 码。 最 好 使 用classvue, 因 为sdk 提 供 的 源 代 码 可 能 并 不 是 产 生 类 的 文 件, 对 不 熟 悉classvue 的 人, 等 价 的 工 具 是sun sdk 提 供 的 类 文 件 内 部 检 查 器javap。

以 下 是 一 张sdk 中 所 有 修 改 的 清 单, 但 是 也 有 可 能 有 疏 漏。 这 里 提 到 的 所 有 修 改 都 在java.lang、java.io、java.awt、java.util 和java.security 包 或 子 包 中, 每 个 包 的 修 改 如 下:

java.lang: 新 方 法、 新 变 量

java.io: 省 略 方 法

java.awt: 新 类、 新 方 法、 新 变 量

java.util: 新 方 法、 新 变 量

java.security: 修 改 接 口
新 类
首 先,microsoft 在 其java sdk 系 统 包 中 增 加 了 新 的 类、 方 法 和 变 量。 所 有 在 完 全 修 饰 名 中 以java.* 开 头 的 叫 做 系 统 包 或 者 核 心java api。 十 六 个 新 类 加 入 到 了java.awt 中, 它 们 是:

microsoft 新 增 加 的awt 同 位 类 的java 类 wbuttonpeer wcheckboxmenuitempeer wcheckboxpeer wchoicepeer
wlabelpeer wlistpeer wmenubarpeer wmenuitempeer
wmenupeer wpopupmenupeer wscrollbarpeer wscrollpanepeer
wtextareapeer wtextcomponentpeer wtextfieldpeer wuipeer

除 了 最 后 一 个, 所 有 的 类 都 是awt 构 件 的 同 位(peer) 类。 同 位 类 是 诸 如 按 钮 和 菜 单 的 图 形 构 件 在 特 定 平 台 的 表 示。 一 般 来 说, 这 些 类 会 出 现 在 不 同 的 包 中, 如sun.awt.windows 或 者sun.awt.motif, 你 可 以 不 使 用 它 们, 故 很 容 易 避 免。wuipeer 也 是 一 个 同 位 类, 但 是 它 支 持microsoft 专 用 的 动 作, 应 该 避 免 使 用 它。 另 外 还 加 入 了 其 他 的 包 私 有(package-private) 类( 也 称 为 友 类, 无 须 增 加 访 问 分 类 符 关 键 字), 如_awtuiband 和_uimenuroot。 因 为 在java.awt 之 外 是 不 可 访 问 的, 故 不 能 直 接 使 用。

新 方 法 和 实 例 变 量
增 加 最 多 的 方 法 是getbasename()。 幸 好 它 是 包 私 有 的。 其 他 的 修 改, 例 如 将classloader 的loadclassinternal() 方 法 由 包 私 有 变 为 私 有 是 由 于 实 现 上 的 差 别, 不 影 响 开 发 者。

不 是 我 忽 视microsoft 的 包 私 有 修 改, 但 是 除 非 开 发 者 自 己 扩 展java 关 键 类 库, 否 则 就 涉 及 不 到 这 些 修 改。 因 为 开 发 者 更 多 的 时 候 是 寻 求 一 种 跨 平 台 的 解 决 方 案, 而 不 是 将 自 己 的 修 改 加 入 到 关 键java 类 库 中 去, 所 以 这 不 是 问 题。 而 真 正 的 问 题 是microsoft 新 加 入 的 公 用 方 法。

关 键java 类 库 中 加 入 的 公 用 方 法 类 新方法
java.awt.eventqueue _postevent(awtevent)
java.awt.font getnativedata()
java.awt.image.colormodel finalize()[was protected]
java.awt.image.directcolormodel gettoolkitdata()
java.awt.image.indexcolormodel getopaque()
gettoolkitdata()
java.awt.systemcolor getwin32index()
java.lang.class getinterface(string)
getmethods(int[])
getmethodfromsignature(string,string)
getdeclaredmethodfromsignature(string,string)
java.lang.runtime getnativeservices()
java.lang.securitymanager checkfiledialog()
checkmultimedia()
checkregistry(int,string)
checksystemstreams(int)
java.lang.verifyerror getauditdetails()
getauditidentifier()
getclassname()
getmethodname()
getpc()
getviolationcode()
getviolationdescription()
java.lang.reflect.method getdescriptor()
getparametercount()
java.util.locale locale(string,string,string,int,int)
getcodepage()
getdefaultlocalelist()
getlcid() [was private]
getlocalefromlcid(int)
java.util.resourcebundle getmenu(string)
getmenubar(string)

除 非 你 只 在microsoft 的 环 境 中 运 行 你 的java 程 序, 否 则 就 应 该 避 免 使 用 这 些 方 法。 除 此 之 外 还 有 三 个 新 的 实 例 变 量 和 为 数 不 少 的 国 际 化 地 区 变 量。

加 入 到java api 中 的 实 例 变 量 类 新变量
java.awt.font pdata
java.awt.systemcolor appworkspace
java.lang.reflect.member public_declared
java.util.locale afrikaans
albanian
australia
basque
belgian
belgian_french
brazilian
bulgarian
byelorus
catalan
croatian
czech
danish
dutch
estonian
finnish
german_austrian
german_swiss
greek
hebrew
hungarian
icelandic
indonesian
ireland
japanese_vertical korean_vertical
latvian
lithuanian
mexican
newzealand
norwegian
norwegian_nynorsk
polish
portugese
romanian
russian
serbian
simplified_chinese_vertical
singapore
slovakian
slovenian
south_africa
spanish
spanish_modern
swedish
swiss
thai
traditional_chinese_vertical
turkish
ukranian

public_decalred 对member 是 全 新 的,appworkspace 对systemcolor 也 是 全 新 的, 而pdata 则 由 私 有 变 为 公 用。 与 其 他 修 改 一 样, 必 须 避 免 使 用。 就locale 对 象 而 言,microsoft 环 境 支 持 另 外 几 种 语 言, 而javasoft 不 支 持。 虽 然 不 使 用 这 些 新 的 地 区 变 量 要 求 你 格 式 化 消 息 时 做 额 外 的 工 作, 但 是 还 是 应 该 避 免 使 用, 而 用 必 要 的 参 数 自 己 创 建 一 个locale 对 象。

对 每 个 新 加 入 的 地 区 变 量, 在java.text.resource 包 中 都 加 入 了 两 个 公 用 类, 因 为sun 的docucentation 特 别 声 明, 不 应 该 直 接 调 用text.resource 中 的api, 所 以 这 也 不 是 问 题。

接 口 修 改
接 口 定 义 了 类 必 须 遵 循 的 部 分 摸 板,microsoft 修 改 了 部 分 安 全 接 口 摸 板:

java 安 全 接 口 中 增 加 的 方 法 接口 新方法
java.security.interfaces.dsaprivatekey getalgorithm()
getencoded()
getformat()
getparams()
java.security.interfaces.dsapublickey getalgorithm()
getencoded()
getformat()
getparams()

当 创 建 一 个 实 现 某 一 接 口 的 类 时, 必 须 定 义 接 口 中 声 明 的 每 个 方 法。microsoft 增 加 了 接 口 中 的 方 法 数 量, 破 坏 了 所 有 实 现 以 前 接 口 的 类。 若 要 创 建 在microsoft 和 非microsoft 环 境 中 都 能 运 行 的 程 序, 只 要 你 在 类 中 实 现 了 修 改 的 接 口, 就 必 须 实 现 其 中 增 加 的 方 法。

com.ms 包
com.ms 是 一 组 与microsoft 建 议 的java 实 现 一 起 发 表 的 类。 所 有 的 类 在com.ms 包 中, 所 以 用netscape navigator/communicator 和java 1.1 都 无 法 访 问。 如 果 你 使 用 了com.ms 包 中 的 类, 便 失 去 了 可 移 植 性。 以 下 是 一 个 例 子: 一 个 不 知 情 者 用getfontmetrics() 从toolkit 类 中 获 取fontmetrics, 此 方 法 的 签 名 说 明 也 是"public fontmetrics getfontmetrics()", 此 方 法 返 回com.ms.awt.fontmetrics 的 一 个 实 例。 如 果 你 将 它 看 作 一 个fontmetrics, 那 么 你 的 程 序 只 能 在microsoft 的java 虚 拟 机 上 运 行。 而 如 果 你 坚 持 用fontmetrics, 则 可 以 移 植。

但 是 避 免 使 用com.ms 时 也 有 一 个 例 外,com.ms.ui 中microsoft 应 用 程 序 基 础 类(afc) 是 用java 写 的, 所 以 可 以 使 用。 然 而, 如 果 你 不 使 用ie 4.0, 就 得 单 独 提 供afc。( 除 非microsoft 将afc 类 捆 绑 到 在 非microsoft 环 境 中 可 用 的 东 西 上, 否 则 必 须 单 独 提 供afc, 因 为afc 类 包 含 在ie4 中, 而 其sdk 依 赖microsoft java 虚 拟 机 特 性。afc 类 不 久 将 会 捆 绑 到 其 他 浏 览 器 上, 如netscape navigator 3.0。 详 细 信 息 参 看microsoft 站 点。)  

sdk 中 得 省 略
在 我 检 查 过 的 类 中, 只 从microsoft 建 议 的java 1.1 实 现 中 省 略 了 一 个 方 法。 省 略 此 多 余 的 方 法 相 对 来 说 并 不 重 要。 确 切 地 说,bytearrayoutputstream 中 接 受 字 符 编 码 名 参 数 的tostring() 方 法 省 略 了。 对 此 省 略 的 回 避 办 法 是 请 求 流 的 字 节 数 组(tobytearray()), 然 后 使 用 接 受 编 码 名 的string 构 造 器。 用 这 两 步, 即 使 用jdk, 也 能 建 立 在microsoft 运 行 时 环 境 中 运 行 的 程 序。

差 别
最 后 我 要 讨 论 的 这 些 修 改 与 新 增 加 的 类 和 省 略 的 方 法 无 关, 而 与 动 作 上 的 差 别 有 关。 无 论 何 时, 只 要 有 一 个 新 的 环 境 推 出, 你 就 有 必 要 弄 清 楚 它 与 你 期 望 的 动 作 有 和 不 同。 例 如,netscape navigator 3.0 beta 5 推 出 时, 浏 览 器 向 程 序 报 告 额 外 的awt 事 件, 如 果 你 的 程 序 没 有 考 虑 额 外 的 事 件, 就 会 不 正 常 动 作。 对 新 的sdk, 我 们 又 得 面 对 这 种 差 别。

起 初microsoft win32 java 虚 拟 机 声 称 是java1.1( 注 意 在"1.1" 的 第 二 个1 后 面 没 有 东 西)。 现 在,sun 推 出 了java 1.1.4 版 本 的sdk, 这 意 味 着 在microsoft java 虚 拟 机 中 并 未 包 括 你 所 期 望 的 错 误 修 正。 也 有 可 能 因 为 实 现 上 的 差 别 或 者microsoft 自 己 修 正 了 这 些 错 误, 并 不 需 要sun 的 这 些 错 误 修 正。 然 而 只 要 看 一 眼 源 代 码 并 作 比 较, 就 会 发 现 明 显 的 功 能 差 别。 如 果sdk 并 未 按 照 你 的 期 望 动 作, 你 需 要 适 当 地 调 整 你 的 程 序。

例 如 使 用java.awt.borderlayout, 当 你 增 加 一 个 没 有 方 位 名(quadrant name) 的 构 件 时, 在jdk 或 者java 运 行 时 环 境(jre) 中, 它 会 出 现 在 中 间 方 位 上。 当 增 加 一 个 非 法 方 位 名 的 构 件 时, 如"top",borderlayout 便 抛 出 一 个illegalargumentexception 异 常。 然 而 在microsoft 环 境 中 运 行 同 一 个 没 有 方 位 名 的 程 序, 构 件 根 本 就 不 会 在 任 何 地 方 显 示( 影 响swing jframe 构 件 使 之 不 可 用 )。 另 一 个 差 别 是 在microsoft 环 境 中,dialog 类 接 受 一 个 空 的 父frame 参 数。 而sun jdk 中 则 抛 出 一 个illegalargumentexception 异 常。 越 多 地 在ie 4.0 下 运 行 程 序, 这 些 差 别 就 会 越 多 地 显 现 出 来。 对 于 更 倾 向 于 技 术 的 读 者, 这 里 有 一 些 更 进 一 步 修 改 的 细 节。 其 他 的 动 作 差 别, 其 中 一 些 是 对 原 来 系 统 的 提 高, 对 开 发 者 是 不 可 见 的。 例 如, 对 象 锁 定 可 以 在 不 同 级 上 实 现。 microsoft 所 做 的 任 何 提 高, 有 望 在sdk 中 得 到 体 现, 反 之 亦 然。microsoft 环 境 中 额 外 的 性 能 提 高 也 会 反 映 到sdk 中。 例 如, 在microsoft 环 境 中, 要 改 变 一 个 构 件 的 颜 色 或 字 体 时, 先 检 查 新 值 是 否 与 旧 值 不 同, 如 果 相 同, 不 做 改 变。 而 在sun 的 环 境 中, 即 使 是 不 必 要 的, 也 盲 目 地 做 改 变。 象 这 样 的 小 的 修 改 可 能 导 致 很 大 的 性 能 提 高。

结 果
毫 无 疑 问,microsoft 对java 关 键 类 库 做 了 修 改。microsoft 能 否 合 法 地 与sun 达 成 协 议, 完 全 掌 握 在 法 院 的 手 中。 虽 然 总 的 来 说, 这 些 修 改 相 对 较 小, 但 毕 竟 是 修 改 了。 如 果 法 院 因 为 这 些 修 改 不 重 要 而 宣 布 其 不 碍 大 局, 那 么 如 何 阻 止 其 他 修 改 呢 ?

以 下 我 们 快 速 回 顾 一 下 这 些 修 改, 以 及 对 开 发 者 及 用 户 带 来 的 问 题。

不 支 持rmi 和jni: 如 果 程 序 需 要 这 些 功 能, 则 不 能 正 常 运 行。 开 发 者 必 须 与sun 的java 运 行 时 环 境(jre) 一 起 发 布 程 序, 以 保 证 有 一 个 兼 容 的 环 境。 这 就 导 致 有 些 在 浏 览 器 中 作 为 小 程 序 运 行 得 更 好 的 程 序, 也 必 须 转 换 为 一 个 单 独 的 应 用 程 序。

增 加 的 类、 方 法 和 变 量: 要 开 发100% 纯java 解 决 方 案, 开 发 者 就 要 避 免 使 用。 虽 然 这 比 较 容 易 实 现, 但 是 当 开 发 者 不 小 心 使 用 了 这 些 不 可 移 植 的 特 征 时, 没 有 类 似 于@ 的 标 志 来 警 告 他 们。 如 果 开 发 者 粗 心, 只 有 等 到 在microsoft win32 虚 拟 机 以 外 的 环 境 中 运 行, 程 序 终 止 运 行 或 者 根 本 就 不 启 动 时, 用 户 才 会 发 现。

在 接 口 中 增 加 方 法: 与 下 一 点 一 起, 这 可 能 是 最 大 的 错 误 之 一。 实 现 被 改 变 接 口 的 类 在microfoft 环 境 中 运 行 的 可 能 性 是 微 乎 其 微 的。 要 使 这 些 类 运 行, 你 必 须 引 入 相 同 命 名 和 相 同 功 能 的 方 法。 为 了 创 建 在microsoft 和 非microsoft 环 境 中 都 运 行 的 解 决 方 案, 开 发 者 必 须 定 义 由microsoft 扩 展 接 口 规 定 的 命 名 和 动 作 的 方 法。 否 则, 以 前 使 用 这 些 接 口 的 可 运 行 的 解 决 方 案 将 不 能 在microsoft win32 虚 拟 机 上 运 行。

省 略bytearrayoutputstream 方 法: 虽 然 这 个 省 略 的 方 法 相 对 并 不 重 要, 但 是 这 可 能 是 最 大 的 错 误 之 一。100% 纯java 程 序 可 能 在netscape navigator 或jdk/jre 中 运 行 得 很 好, 但 就 是 不 能 在microsoft 环 境 中 运 行。 除 非 间 接 地 使 用 了 此 方 法, 否 则 很 容 易 绕 开 它。 然 而 对 已 分 发 的 产 品, 这 意 味 着 无 尽 头 地 浪 费 的 技 术 支 持 时 间。 可 能 必 须 更 新 和 重 新 分 发 产 品, 以 支 持microsoft 的 不 兼 容 环 境。

使 用com.ms 类:microsoft 没 有 使 用 标 准 的 包 命 名 约 定 - 逆 域 名 命 名 法, 而 使 用 了"ms.com", 它 恰 好 是morgan stanley 的 域 名。 应 该 鼓 励 这 种 扩 充。 使 用 其 中 的 大 部 分 功 能 将 使 你 约 束 在microsoft 环 境 中, 因 此 这 是 开 发 者 必 须 明 确 选 择 的。 不 象 前 面 提 到 的 修 改, 这 些 功 能 不 会 意 外 地 使 用 到。 只 要microsoft 专 用java 程 序 被 正 确 地 标 志, 用 户 不 会 有 问 题。

动 作 差 别: 应 用 程 序 编 程 接 口(api) 允 许 实 现 上 的 动 作 差 别。 这 些 差 别 中 有 些 是microsoft 试 图 减 少1.1 awt 中 不 兼 容 而 做 的 修 改, 有 些 则 不 是, 而 有 些 带 来 了 性 能 上 的 提 高。 如 果 开 发 者 依 赖 特 定 开 发 工 具, 而 这 种 工 具 存 在 问 题 的 话, 其 中 一 些 差 别 会 给 开 发 者 和 用 户 带 来 困 扰。
结 论
不 幸 的 是,java 世 界 不 再 太 平。 随 着java 1.2 第 一beta 版 发 布 的 临 近,microsoft 表 示 将 不 支 持 其 中 的 部 分 功 能。 这 简 直 就 是ibm 对apple(pc 对mac) 的 翻 版。 虽 然microsoft 和sun 为java 工 具 箱 中 包 括 什 么 争 论 不 休, 而 开 发 者 只 是 想 找 份 工 作 做。 谁 最 终 将 会 在 法 院 中 获 胜, 时 间 会 说 明 一 切。 到 那 时, 开 发 者 需 要 理 解 争 论 的 技 术 和 做 有 根 据 的 决 定。 除 非 这 两 个 冤 家 重 新 走 到 一 起, 否 则 用 户 和 开 发 者 就 象 夹 在 老 虎 钳 中, 难 以 做 出 决 定。 虽 然 平 台 间 的 绝 大 部 分 差 别 是 很 小 的, 但 是 毕 竟 存 在。 你 是 放 弃java 的" 编 写 一 次, 随 处 运 行" 哲 学, 使 用microsoft 虚 拟 机 的 专 用 扩 展, 还 是 跟 随sun 的100% 纯java 原 则 呢 ? 如 果 你 不 需 要jni 和rmi, 则 很 容 易 选 择。

感 谢 上 帝, 用microsoft sdk 仍 然 能 创 建100% 纯java 解 决 方 案。 只 要 避 免 使 用 新 增 到 关 键java 类 库 中 的 类、 方 法、 变 量, 以 及 不 可 移 植 的com.ms 包, 你 还 能 创 建 跨 平 台 的java 程 序。 只 要 绕 开 增 加/ 省 略 的 动 作, 你 还 能 用java 1.1 认 证 的 工 具, 如sun jdk、jbuilder、visualage for java 或visual cafe 2.0 创 建 可 以 在ie 4.0 上 运 行 的 程 序。

扫描关注微信公众号