问题

微软当年的 J++ 究竟是什么?为什么 Sun 要告它?

回答
微软当年推出的 J++,简单来说,是微软自己开发的一个版本的 Java 语言。你可以把它想象成微软对 Java 这套语言和运行环境的“再创作”。

Java 语言最初是由 Sun Microsystems(后来被 Oracle 收购)在 90 年代中期推出的,以其“一次编写,到处运行”的跨平台特性迅速获得了巨大的成功。Sun Microsystems 围绕 Java 构建了一个庞大的生态系统,包括 Java Development Kit (JDK) 也就是开发 Java 程序所需的工具包,以及 Java Runtime Environment (JRE) 也就是运行 Java 程序所需的虚拟机和类库。

微软当然看到了 Java 的巨大潜力,他们也想在蓬勃发展的互联网时代分一杯羹。于是,微软决定在自己的 Windows 平台上实现 Java。但微软并没有完全按照 Sun Microsystems 的规范来做,而是加入了许多他们自己特有的功能和扩展,并给它起了个名字叫做 "Microsoft Visual J++"。

你可以把 J++ 理解成一个“特供版”的 Java。它在语法上基本上兼容 Java,你用 J++ 写的很多代码也能在标准的 Java 环境下运行。但微软在 J++ 里加入了很多 Windows 特有的技术,比如 COM (Component Object Model) 组件对象模型。这就像是微软在 Java 这门语言的“车身”上,又塞进了很多自家特有的“发动机”和“电子设备”,让它能更好地与 Windows 系统深度整合,并且提供一些标准 Java 没有的、或者在 Windows 上实现起来更方便的功能。

那么,为什么 Sun Microsystems 要告微软呢?这背后主要是因为版权、许可协议和商业利益的冲突。

Sun Microsystems 在推出 Java 时,确实采取了一种比较开放的策略,允许第三方实现 Java 虚拟机和开发工具,但同时也设定了一些规则和要求。其中最重要的一点是,任何实现 Java 的厂商,都需要遵循 Sun 对 Java 的技术规范,并且需要通过 Sun 的兼容性测试。通过这个兼容性测试,Sun 才能确保各个版本的 Java 能够真正做到“一次编写,到处运行”,维护 Java 的跨平台承诺。

微软的 J++,虽然表面上看起来是 Java,但它在技术实现上,以及最重要的——它对 Java 规范的遵循程度上,与 Sun 的要求存在很大的出入。微软为了让 J++ 与 Windows 平台更紧密地结合,加入了很多只有在 Windows 上才能实现的特性,并且这些特性并没有得到 Sun 的认可。更关键的是,微软没有按照 Sun 的规定,通过 Sun 的官方兼容性测试。

Sun Microsystems 认为,微软这种做法,破坏了 Java 的核心理念——跨平台性。用户如果习惯了使用 J++ 开发,然后期望他们的 Java 程序能够在其他操作系统上也能运行,很可能会因为 J++ 的那些“特供”功能而遇到问题。这不仅损害了 Java 的声誉,也威胁到了 Sun 在 Java 生态系统中的控制力和商业模式。

而且,微软当时正在大力推广自己的 Windows 平台和 ActiveX 等技术,他们希望通过 J++ 来吸引开发者,让他们在 Windows 平台上构建应用程序,而不是在其他平台上。从 Sun 的角度来看,微软的 J++ 就像是微软在 Java 这个“公共语言”的基底上,强行打上了“Windows Only”的烙印,这与 Java 的开放和跨平台精神背道而驰。

简单来说,Sun Microsystems 觉得微软是在“偷梁换柱”,借着 Java 的名义,实际上是在推广自己的封闭生态系统,并且没有遵守当初的合作约定。所以,Sun 认为微软的行为构成了对 Java 品牌和技术的侵犯,从而采取了法律手段来维护自己的权益。

这场官司最终以微软同意停止销售和支持 J++,并更改其 Java 开发工具的名称(后来变成了 Visual J,而 J 更加倾向于 .NET 平台,与 Java 已经有了较大的区别)而告一段落。这件事也对 Java 的发展和微软在 Java 领域的策略产生了深远的影响。

网友意见

user avatar

目前排名第一的

猫杀

的答案不错。我想就所谓“Microsoft J++”到底是什么稍微补充几点。

本文提到的“Sun JVM”主要说的是Sun JDK 1.0.2带的那个元祖JVM。它在后来的Sun JDK里被称为Classic VM,再后来被HotSpot VM所替代。

当时(Sun JDK 1.0.2)的Java跟现在的Java不可同日而语。别提标准不标准,当时的Java毛都没有,很多东西所谓“标准”就是“Sun怎么实现”。

为什么Sun要告微软?微软“不乖”,“擅自”扩展Java让它在Windows上变得更好自然是一方面;另一方面Sun对它的Java合作伙伴们普遍态度恶劣,非常傲慢和小心眼,这才是更重要的方面。

这方面请参考另一个问题的回答:

如果当时 Sun 没有起诉微软,而微软继续保持对 Java 的热情的话,Java 的现状会是怎样? - RednaxelaFX 的回答

另外,想从别的侧面看看当年Sun的行为,看看1997年Sun在benchmark上作弊的事情:

Sun accused over JIT compiler results

。这还不是Sun第一次做这种事嗯。

关于控告的过程,请参考当时的新闻稿:

Washingtonpost.com: WashTech -- U.S. v. Microsoft Special Report

Microsoft J++

Microsoft J++是外界对微软所实现的Java的开发套件和运行时环境的统称。微软自己其实并没有一个叫做“Microsoft J++”的产品(或语言)。微软一直觉得自己实现的就是Java语言,只是稍微根据Windows环境的需要“增强”了一点而已。

微软在JDK 1.0.x时期就获得了Java的授权,将Java移植到Windows平台上。当时的Java真是烂得掉渣,JVM的速度又慢,Java核心库的功能又是要啥啥没有:

例如说能用的容器数据结构就只有Vector、Stack(包装了Vector)、Hashtable(不允许null值)、BitSet,连LinkedList都还没有——“谁会要用链表呢”。

java.math、java.text、java.sql、java.rmi之类的重要的类库都还不存在,locale支持还不存在,图形库只有又慢又不好用的AWT⋯

嗯对,JDK 1.0.2的时候连反射都还没API,java.lang.reflect也还不存在。Java语言里“接口”这个语言结构也还不存在。

JNI(Java Native Interface)标准也还不存在。Sun JDK 1.0.2只有一个非常原始的native interface,而它允许native代码直接访问Java对象的内部结构,既不安全也不可移植。更新信息可以参考当时的文档:

Integrating Native Methods into Java Programs

而这个时候Windows上已经有很多可用的库,更重要的是:

  • 它们有很多都以COM的方式暴露接口
  • Java的对象技术其实跟COM有许多重叠之处

于是让Java能够更好的利用Windows上已有的资源,真正在Windows上成为一等公民,微软给Java添加了:

  • J/Direct与RNI(Raw Native Interface):用于与native代码交互
  • Java/COM:让Java能够使用COM的库,也让Java程序能够暴露出COM接口,便于与其它程序交互。参考这里:Can You Implement COM Components Using Java?
  • 委托(delegate):现在Java 8也有lambda,大家都知道这个是什么了。当时要引入委托主要是为了更好的支持事件模型的回调。详情可以参考微软对Java委托的专利:Patent WO1999063433A1,以及MSDN的文档 Delegates in Visual J++ 6.0。微软当时为Java实现了委托之后把全套代码交给了Sun,向Sun申请添加该功能到标准Java。结果Sun暴跳如雷急忙批判微软要分裂Java…
  • 还有一大堆的库。例如Windows Foundation Classes (WFC)。WFC包装了Win32和DHTML的图形组件库。Win32的部分跟后来.NET的Windows Forms(WinForms)很像。
  • 等等⋯

微软版的RNI在Sun版的JNI之前就已发布,自然就不大愿意再实现一个功能非常相似的东西。但微软决定不在MSJVM里实现完整的JNI成为了后来打官司的关键因素之一。

当年微软给Java加了的功能,现在Oracle在一点点给Java加上⋯

  • Java SE 8给Java语言加上了lambda与method reference;
  • Java SE 9正在计划给Java加上跟J/Direct类似的新的、更方便的native interface

Microsoft Visual J++

Visual J++,这是一个实际存在的产品的名字。它是一个用于开发Java应用程序的IDE,里面还包含有IE3.0之类的“附属物”。Visual J++有单独发布的版本,后来被整合到Visual Studio里发布。

Microsoft SDK for Java (MSJDK)

这是Sun JDK的微软版对应物,独立于Visual J++免费发布。它包含开发Java应用程序所需要的工具套件,例如Java源码编译器 jvc(与Sun JDK的javac对应),Java的命令行启动程序 jview (与Sun JRE的java命令对应) ,Java Applet Viewer,Java核心库,还有Java虚拟机(MSJVM),等。

有个有趣的工具叫做 jexegen。顾名思义,它用于为Java程序创建一个可执行程序,把Java程序所需的Class文件打包在生成的exe里。这跟后来.NET Assembly的做法很接近:它是一个PE文件,不过启动之后马上会去加载MSJVM来执行打包的Class文件。能生成出可执行文件让Java写出来的程序能更符合Windows的用户习惯。

Microsoft Compiler for Java (jvc)

jvc 是微软自己实现的Java源码编译器,应该是用C++实现的(求证)。

它的编译速度非常快,而且编译时会做许多优化,编译出来的代码质量也比较高。

相比之下,同时期Sun的javac是用Java实现的,编译速度慢一些;虽然也做一定量的优化,但没 jvc 做得深。

jvc 跟当时IBM的

Jikes编译器

(跟后来的Jikes RVM不是同一个东西)地位相似。两者都用native语言实现(Jikes用C++),编译速度都比较快,而且都做比较多优化。

同年代同样用native语言实现的Java源码编译器还有Symantec Café Compiler。

jvc 支持所有标准的Java语言特性,外加支持如delegate、J/Direct之类的微软扩展的特性。

话说有个黑历史非常搞笑:Sun在控告微软的jvc不兼容Java规范的时候,指责jvc生成的Class文件通不过TCK1.1;然后微软不但说明Sun没用对命令(故意打开了微软扩展来测试),而且进一步说明Sun的javac其实也不能完全通过TCK1.1;关掉了扩展的jvc能通过的TCK1.1测试比Sun的javac能通过更多。

Microsoft Virtual Machine for Java (MSJVM, Microsoft VM, MSVM)

这是微软实现的JVM。最初的代码来自Sun授权的Sun元祖JVM,后来被魔改成Windows上最快的JVM实现。

IE3 Beta 1的时候带的MSJVM还只有解释器,到IE3 Beta 2就开始带有JIT编译器了。

MSJVM魔改了Sun JVM核心的每一方面。

  • 对象模型:Sun JVM的对象模型把“对象头”放在了handle里,使“对象头”跟对象实例数据分离到不同的地方了。MSJVM去掉了handle这层间接,于是把对象头与对象实例数据重新“粘”到了一块。关于MSJVM的对象模型,我在另一个回答里简单提了一下:为什么bs虚函数表的地址(int*)(&bs)与虚函数地址(int*)*(int*)(&bs) 不是同一个? - RednaxelaFX 的回答
  • 基于直接指针而不是基于handle的引用,访问效率更高。
  • GC:准确式的、分两代的copying GC。文档里还专门说了没使用mark-compact算法。当时的Sun JVM使用的是半保守式、不分代的mark-sweep(带可选compaction) GC。
  • 对象同步:使用synchronization block而不是老Sun JVM的monitor cache。在对像头里包含有一个指向synchronization block的指针;该指针位于对象的负偏移量上。后来的CLR的对象头采用了同样的布局。在对象头里持有这样的指针大幅减少了查找对象的monitor的事件。Sun JVM是维护一个全局的用hash table实现的“monitor cache”,把对象的handle强制转换成int当作key去查找这个cache里的monitor,每次查找都是一个hash lookup。
  • 线程:使用native线程,管理线程用的数据结构稍微调整过。Sun JVM在Windows上的版本用native thread,而在Solaris上的版本则是使用green thread(JVM自己调度的用户级线程)。
  • 添加了JIT编译器:Sun JVM在JDK 1.0.x的时候只有个很简陋的JIT编译器接口,但没有发布JIT编译器的实现。MSJVM改造了这个接口并且提供了一个当时性能还不错的JIT编译器实现,而且配合准确式GC提供必要的信息。
  • RNI:在Sun JVM的native interface的基础上衍生出的一套native interface。
  • Java/COM在MSJVM内的支持

MSJVM基本没怎么改动的可能也就是解释器的核心循环了。原本在Sun JDK 1.0.2的时候,Sun JVM的解释器循环用纯C实现,写得很直观但性能很渣;到Sun JDK 1.1.0的时候

改为用汇编实现

,写得比较高效,所以也就没啥必要魔改这部分,小改动然后直接用就好。顺带一提,Sun JDK 1.1.0的JVM的解释器,在x86上的版本是Intel贡献给Sun,而不是Sun自己写的⋯呃呵呵。

Sun那边的JIT编译器有好多黑历史⋯Sun JDK 1.0.2自己没有带JIT,不过有一个单独销售的产品叫“Java Workshop”,里面带有一个能插入Sun JVM的JIT,这个JIT编译器叫做“sunwjit”。

可以从

这里

下载到描述sunwjit的一篇文章(CompileJava97.pdf,“Compiling Java Just in Time”)。

后来Sun JDK 1.1.x的时候开始带JIT发布了,但却只在Solaris版上带有sunwjit,而在Windows版上带的是Symantec的JIT(“symcjit”)。

据说James Gosling原本自己写过一个JIT编译器,但是没发布被抛弃了。不知道这跟sunwjit是啥关系呢。

Microsoft Internet Explorer 3.0 (IE3.0)

IE3.0真是当年的技术急先锋。一方面搭载了JScript来跟Netscape的JavaScript抗衡,另一方面捆绑了MSJVM以便支持Java。

先写这么多吧⋯

=============================================

后话

所以说当时MSJVM至少可以从三个地方获取:IE3、Visual J++/Visual Studio、MSJDK。MSJVM的许可证也允许第三方程序捆绑它发布。

顺带一提,根据

Patrick Dussud在Channel 9上的一个访谈

里提到的,微软里其实还有过一小撮人做过一个非正式项目,是写一个全新的、“clean-room”(不衍生自Sun的代码)的JVM原型。这个项目最后没有进入产品。或许如果当年Sun没有禁止微软开发新版本Java的话,微软也会像IBM开发出全新、clean-room的J9 VM一样有自己独立的JVM。

然而历史没有如果。那个clean-room的JVM原型为后来的CLR的研发积累了不少经验。

我觉得现在这样也挺好的。.NET总算没把Java所有的历史包袱都带上,CLI(Common Language Infrastructure)的基础设计又比JVM的更进步和完善。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有