发信人: lidun() 
整理人: zjxyz(2002-01-26 13:38:08), 站内信件
 | 
 
 
如 何 避 免Microsoft 非 标 准Java SDK 的 潜 在 危 险 
       ─ ─Microsoft 在 其 实 现 的Java 1.1 关 键 类
       库 中 所 增 加 或 省 略 的 方 法、 类 和 变 量 
 
       
 
                摘 要Sun 在 宣 布 其 控 诉Microsoft 违 反Java 兼 容 性  问 题 协 议 的 起 诉 中 提 出, 
       对Java 关 键 类 库 的 修 改 是 错 误 的。 在 本 文 中,JavaWorld  投 稿 人、Java 开 发 者John 
       Zukowsk 对Microsoft 新 的SDK 中 到 底 增 加 和 省 略 了 那 些 类 、 方 法 和 变 量 做 了 简 明、 全 面 
       的 总 结。 本 文 提 供 了Sun 和 其 他 公 司 仅 仅 暗 示 的、 在M icrosoft Java SDK 中 发 现 的 修 改 的 
       全 面 列 表, 以 及 每 个 修 改 的 含 义 和 开 发 者 如 何 定 位  任 一 改 变/ 增 加/ 省 略。 总 之, 本 文 说 明 
       了 用Microsoft 产 品 创 建 真 正 的" 编 写 一 次, 随 处 运 行"  的 应 用 和 创 建 在Microsoft 
       Internet Explorer 4.0 上 运 行 的 程 序 时 所 必 须 知 道 的。 
                 Microsoft Internet Explorer 4.0 和2.0 版 的Java SDK 均  已 推 出。 根 
       据Microsoft Win32 Java 虚 拟 机 的 发 布 注 释,IE 4.0 与 新 的S DK 中 的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 类 
             WButtonPeerWCheckboxMenuItemPeerWCheckboxPeerWChoicePeer 
              WLabelPeerWListPeerWMenuBarPeerWMenuItemPeer 
             WMenuPeerWPopupMenuPeerWScrollbarPeerWScrollPanePeer 
             WTextAreaPeerWTextComponentPeerWTextFieldPeerWUIPeer 
         
                除 了 最 后 一 个, 所 有 的 类 都 是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.FontgetNativeData() 
             java.awt.image.ColorModelfinalize()[was protected] 
             java.awt.image.DirectColorModelgetToolkitData() 
             java.awt.image.IndexColorModelgetOpaque() 
             getToolkitData() 
             java.awt.SystemColorgetWin32Index() 
             java.lang.ClassgetInterface(string) 
             getMethods(int[]) 
             getMethodFromSignature(string,String) 
             getDeclaredMethodFromSignature(String,String) 
             java.lang.RuntimegetNativeServices() 
             java.lang.SecurityManagercheckFileDialog() 
             checkMultimedia() 
             checkRegistry(int,String) 
             checkSystemStreams(int) 
             java.lang.VerifyErrorgetAuditDetails() 
             getAuditIdentifier() 
             getClassName() 
             getMethodName() 
             getPC() 
             getViolationCode() 
             getViolationDescription() 
             java.lang.reflect.MethodgetDescriptor() 
             getParameterCount() 
             java.util.LocaleLocale(String,String,String,int,int) 
             getCodePage() 
             getDefaultLocaleList() 
             getLCID() [was private] 
             getLocaleFromLCID(int) 
             java.util.ResourceBundlegetMenu(String) 
             getMenuBar(String) 
         
                除 非 你 只 在Microsoft 的 环 境 中 运 行 你 的Java 程  序, 否 则 就 应 该 避 免 使 用 这 些 
       方 法。 除 此 之 外 还 有 三 个 新 的 实 例 变 量 和 为 数 不 少  的 国 际 化 地 区 变 量。 
       加 入 到Java API 中 的 实 例 变 量 类新变量 
             java.awt.FontpData 
             java.awt.SystemColorappWorkspace 
             java.lang.reflect.MemberPUBLIC_DECLARED 
             java.util.LocaleAFRIKAANS 
             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 对Sy stemColor 也 是 全 新 
       的, 而pData 则 由 私 有 变 为 公 用。 与 其 他 修 改 一 样, 必  须 避 免 使 用。 就Locale 对 象 而 
       言,Microsoft 环 境 支 持 另 外 几 种 语 言, 而JavaSoft 不 支 持 。 虽 然 不 使 用 这 些 新 的 地 区 变 
       量 要 求 你 格 式 化 消 息 时 做 额 外 的 工 作, 但 是 还 是 应  该 避 免 使 用, 而 用 必 要 的 参 数 自 己 创 
       建 一 个Locale 对 象。 
                对 每 个 新 加 入 的 地 区 变 量, 在java.text.resource  包 中 都 加 入 了 两 个 公 用 类, 
       因 为Sun 的docucentation 特 别 声 明, 不 应 该 直 接 调 用text. resource 中 的API, 所 以 这 也 
       不 是 问 题。 
       接 口 修 改
                接 口 定 义 了 类 必 须 遵 循 的 部 分 摸 板,Microsoft  修 改 了 部 分 安 全 接 口 摸 板: 
       Java 安 全 接 口 中 增 加 的 方 法 接口新方法 
             java.security.interfaces.DSAPrivateKeygetAlgorithm() 
             getEncoded() 
             getFormat() 
             getParams() 
             java.security.interfaces.DSAPublicKeygetAlgorithm() 
             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.FontMet rics 的 一 个 实 例。 
       如 果 你 将 它 看 作 一 个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 实 现 中 省 略 了 一 个 方 法。 
       省 略 此 多 余 的 方 法 相 对 来 说 并 不 重 要。 确 切 地 说,B yteArrayOutputStream 中 接 受 字 符 编 
       码 名 参 数 的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 中。 例 如, 在Microso ft 环 境 中, 要 改 变 一 个 构 件 的 颜 色 
       或 字 体 时, 先 检 查 新 值 是 否 与 旧 值 不 同, 如 果 相 同,  不 做 改 变。 而 在Sun 的 环 境 中, 即 使 是 
       不 必 要 的, 也 盲 目 地 做 改 变。 象 这 样 的 小 的 修 改 可  能 导 致 很 大 的 性 能 提 高。 
       结 果
                毫 无 疑 问,Microsoft 对Java 关 键 类 库 做 了 修 改。 Microsoft 能 否 合 法 地 与Sun 
       达 成 协 议, 完 全 掌 握 在 法 院 的 手 中。 虽 然 总 的 来 说,  这 些 修 改 相 对 较 小, 但 毕 竟 是 修 改 了。 
       如 果 法 院 因 为 这 些 修 改 不 重 要 而 宣 布 其 不 碍 大 局,  那 么 如 何 阻 止 其 他 修 改 呢 ? 
                以 下 我 们 快 速 回 顾 一 下 这 些 修 改, 以 及 对 开  发 者 及 用 户 带 来 的 问 题。 
         不 支 持RMI 和JNI: 如 果 程 序 需 要 这 些 功 能, 则 不 能 正  常 运 行。 开 发 者 必 须 与Sun 的Java 
         运 行 时 环 境(JRE) 一 起 发 布 程 序, 以 保 证 有 一 个 兼 容  的 环 境。 这 就 导 致 有 些 在 浏 览 器 中 
         作 为 小 程 序 运 行 得 更 好 的 程 序, 也 必 须 转 换 为 一  个 单 独 的 应 用 程 序。 
         
         增 加 的 类、 方 法 和 变 量: 要 开 发100% 纯Java 解 决 方 案 , 开 发 者 就 要 避 免 使 用。 虽 然 这 比 
         较 容 易 实 现, 但 是 当 开 发 者 不 小 心 使 用 了 这 些 不  可 移 植 的 特 征 时, 没 有 类 似 于@ 的 标 志 
         来 警 告 他 们。 如 果 开 发 者 粗 心, 只 有 等 到 在Microsof t Win32 虚 拟 机 以 外 的 环 境 中 运 
         行, 程 序 终 止 运 行 或 者 根 本 就 不 启 动 时, 用 户 才 会  发 现。 
         
         在 接 口 中 增 加 方 法: 与 下 一 点 一 起, 这 可 能 是 最 大  的 错 误 之 一。 实 现 被 改 变 接 口 的 类 
         在Microfoft 环 境 中 运 行 的 可 能 性 是 微 乎 其 微 的。 要  使 这 些 类 运 行, 你 必 须 引 入 相 同 命 
         名 和 相 同 功 能 的 方 法。 为 了 创 建 在Microsoft 和 非Micr osoft 环 境 中 都 运 行 的 解 决 方 
         案, 开 发 者 必 须 定 义 由Microsoft 扩 展 接 口 规 定 的 命  名 和 动 作 的 方 法。 否 则, 以 前 使 用 
         这 些 接 口 的 可 运 行 的 解 决 方 案 将 不 能 在Microsoft Wi n32 虚 拟 机 上 运 行。 
         
         省 略ByteArrayOutputStream 方 法: 虽 然 这 个 省 略 的 方 法  相 对 并 不 重 要, 但 是 这 可 能 是 
         最 大 的 错 误 之 一。100% 纯Java 程 序 可 能 在Netscape Navig ator 或JDK/JRE 中 运 行 得 很 
         好, 但 就 是 不 能 在Microsoft 环 境 中 运 行。 除 非 间 接 地  使 用 了 此 方 法, 否 则 很 容 易 绕 开 
         它。 然 而 对 已 分 发 的 产 品, 这 意 味 着 无 尽 头 地 浪 费  的 技 术 支 持 时 间。 可 能 必 须 更 新 和 重 
         新 分 发 产 品, 以 支 持Microsoft 的 不 兼 容 环 境。 
         
         使 用com.ms 类:Microsoft 没 有 使 用 标 准 的 包 命 名 约 定  - 逆 域 名 命 名 法, 而 使 用 
         了"ms.com", 它 恰 好 是Morgan Stanley 的 域 名。 应 该 鼓 励  这 种 扩 充。 使 用 其 中 的 大 部 分 
         功 能 将 使 你 约 束 在Microsoft 环 境 中, 因 此 这 是 开 发  者 必 须 明 确 选 择 的。 不 象 前 面 提 到 
         的 修 改, 这 些 功 能 不 会 意 外 地 使 用 到。 只 要Microsof t 专 用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 程 序。 只 要 绕 开 增 加/ 省 略 的 动 作, 你 还 能 用Ja va 1.1 认 证 的 工 具, 如Sun 
       JDK、JBuilder、VisualAge for Java 或Visual Cafe 2.0 创 建 可 以  在IE 4.0 上 运 行 的 程 
       序。 
 
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.97.186.53]
  | 
 
 
 |