【CSDN 编者按】Java最初被吹捧为"杀手级"的桌面语言,但在21世纪初,它逐渐走向默默无闻。这篇文章是Java开发者所写的回顾桌面Java历史的系列文章的首篇。他认为Java是现代桌面应用程序的一个引人注目的平台,并且解释了他创建jDeploy(一个对开发者友好的Java桌面部署工具)的原因。
原文地址:
https://jdeploy.substack.com/p/the-decline-and-fall-of-java-on-the
本文由CSDN翻译,转载需注明来源出处。
还记得我在90年代末上大学时,Java 是我们计算机课程中必学的官方首选语言。当时,虽然有部分课程使用的是 C、C++,但大多数基础内容都是用 Java 来演示的。而且有的课程作业要求必须要用Java完成。(到了高年级可以自由选择其他语言完成作业)
那时,我对Java的接触仅限于Applets,对于它的地位和相比于之前改进的地方,我一概不知。因为没有更深的了解,我感觉像是被欺骗了,我认为Java只是一种“toy language”(toy language是指一种用于一般指令目的的编程语言,但在实际执行程序时通常是不充分的),而所有"真正的"开发都是用C++等语言完成的。
Java很慢
我想可能任何曾经使用过Java GUI应用程序或带有小程序的网页的人,都会觉得"Java很慢"吧。那个时代唯一用Java编写的桌面应用程序是开发工具(我想到的是ArgoUML和NetBeans),它们不仅有很多bug,而且速度很慢,从滚动到打开菜单都有延迟。
有些教授仍然相信Java的潜力,并且坚持认为,由于它的即时编译功能,Java实际上是相当快的——而且,"理论上 "一旦编译了代码路径,就会和C++运行得一样快(甚至更快)。但是在我看来,这就像皇帝的新衣。
Java应用程序不是"真正的"应用程序
另外一点是我们用Java写的应用程序不是本地的应用程序,这让Java显得很“次等”。在"构建 "了应用程序之后,会得到一堆.class后缀文件,或者得到一个.jar后缀文件,这些只有在计算机安装了Java之后才能运行。而我在BCIT的同学和朋友所做的项目,是现实生活中的可执行文件。双击就可以运行,就像一个真正的专业应用程序——在窗口或屏幕的顶部有所有应该有的菜单,这让我感到有点眼红。
于是,我询问了我的一个教授能否制作本地可执行文件,他不明白我为什么想这么做:"这将否定Java所有的跨平台优势。一旦你把它编译成一个本地可执行文件,它就不再是跨平台的了"。
但是他还是给了我一些建议,让我研究一下Java WebStart,它可以让Mac和Windows的用户更容易安装我的应用程序,而不是将其作为一个本地捆绑程序。WebStart听起来很有趣,但我还是觉得,这不是我想要的。即使WebStart允许我发布应用程序,也还是需要用户安装Java后才能使用。(尽管在2001年左右的这个时候,Java已经预装在大多数电脑上了),而且对于那些习惯于下载后只需双击就能打开的用户来说,这似乎很陌生。
在试验了几个WebStart应用程序后,其结果充其量只能算是平庸的。这些应用程序在下载更新时打开速度总是很慢,而且它们不能很好地与操作系统结合,这让我感到很失望。
但我没有放弃,当时有一些第三方工具把Java应用打包成本地可执行文件,但它们价格不菲,而且 "只适用于Windows"。然后,我又把希望寄托于GCJ,GNU的Java编译器声称能够将Java编译成机器码,但它只适用于一个API子集,而且不支持Swing——所以GUI也不行,除非你想使用本地GUI工具包。
当时的我认为,对于桌面开发来说,Java是一个死胡同,除非我想把应用设计成一个小程序——那时,与Flash等更轻、更快的技术相比,Applets已经不行了。
Applets:杀手级应用
谈到Java在桌面开发的历史,就不得不提到Applet。Applets在1995年具有划时代的意义——它能让你在网页中拥有交互式2D图形和动画,这是前所未有的。一开始(Java1.0时),Java解释器是作为浏览器的一部分提供的,但后来,这种模式就变成了通过插件使用系统安装的Java运行环境。
最初,嵌入小程序只需要将.jar文件(或.class文件)上传到Web服务器,并在网页中添加<applet>
标记。后来随着Java新版本的发布和IE的出现,嵌入小程序所需的HTML代码变得越来越复杂,不同的标签用于不同的浏览器和版本或Java。虽然据宣传,<applet>
标签是在 “多浏览器”环境中嵌入小程序的正确方法,但IE使用<object>
标签,而Mozilla使用<embed>
标签。
现在 ,你需要做的的不是:
```
<APPLET code="MyAppletClass.class" archive="Applet.jar, EJB.jar" width="600" height="500" >
</APPLET>
```
而是:
```
<OBJECT classid="clsid: 8AD9C840-044E-11D1-B3E9-00805F499D93"
width="600" height="500">
<PARAM NAME=CODE VALUE=MyAppletClass.class>
<PARAM NAME="archive" VALUE='Applet.jar, EJB.jar'>
<PARAM TYPE="application/x-java-applet;version=1.5.0">
<PARAM NAME="scriptable" VALUE="false">
<PARAM NAME="cache-option" VALUE="Plugin">
<PARAM NAME="cache-archive" VALUE="Applet.jar, EJB.jar">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.5.0" CODE=MyAppletClass.class
ARCHIVE="Applet.jar, EJB.jar" WIDTH="600" HEIGHT="500"
scriptable="false">
<NOEMBED>
</COMMENT>
</NOEMBED>WebSphere Java Application/Applet Thin Client for
Windows is required.
</EMBED>
</OBJECT>
```
这导致处理未安装Java的系统变得很困难。构建一个小程序时,由NetBeans生成的嵌入代码相当复杂,并且包含JavaScript尝试检测是否安装了Java,如果没有安装,则会提供一个从Sun网站下载Java的链接。
在Java1.3中,Applet的用户体验非常糟糕,以至于Applet只有一种体制环境中(在这种体制环境中,系统管理员可以完全控制用户安装的软件)才实用。在网页中添加简单的交互性不再是一种实用的方法。
到2001年,Applet已经基本走到头了。Flash已经取代它成为基于浏览器的交互式媒体的标准,因为它更简单、更小、更快,并且拥有更好的安装基础(大约99%的计算机都安装了它)。
到这个时候,Applet也给Java带一些负面影响,因为经常出现安全漏洞而被宣传为“Java安全漏洞”。让人感觉任何用Java编写的东西都是存在安全威胁的,尽管这些“漏洞”通常只适用于Applet。
我认为Applet从来不是一种发布桌面应用程序的可行方式,但作为一种有趣的技术,它们经久不衰。
GUI工具包:AWT,Swing和SWT
我刚开始使用Java的时候,它的原始GUI工具包AWT(Abstract Windowing oolkit)就已经过时了,Java的新“轻量级”工具包——Swing风靡一时。简而言之,AWT是一个“重量级”工具包,它提供了一个用于处理原生小部件的API。重量级UI库的问题在于难以维护,并且受到底层平台可用组件的限制。相比之下,Swing是一个轻量级的工具包,它可以绘制所有自己的小部件,这更容易维护和构建跨平台界面。
Swing有一个可插入的UI,可以对其进行样式设置,模仿本机平台的外观。在Mac上运行时,Swing UI看起来与原生Cocoa应用程序一样。在Windows上运行时,它看起来像Windows。它还允许自定义不符合特定平台的外观,非常灵活。
在2000年代初期的计算机上,Swing接口也是出了名的滞后。NetBeans在我的iMac 233MHz上根本没法用。但它能在我父亲的G4 400MHz上使用,虽然使用感极差。
在当时,用Java构建GUI需要对摩尔定律(即集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍。摩尔定律是内行人摩尔的经验之谈,并非自然科学定律,它一定程度揭示了信息技术进步的速度)有极大的信心。它现在非常慢,但可能再发展几年速度会有很大提升。
2002年,我惊喜地发现了Eclipse和SWT——一种似乎可以解决性能问题的Java GUI开发替代方案。Eclipse使用(并且仍然使用)SWT,标准小部件工具包,一个新的“重量级”Java UI工具包。Eclipse(使用SWT构建)明显比NetBeans(使用Swing构建)响应速度更快,因此从表面上看,Eclipse似乎更胜一筹。
SWT不需要绘制自己的小部件,而只是为平台原生小部件提供绑定,所以使用它构建的应用程序感觉更原生,并且响应速度更快。
然而,SWT最后也让我失望了。Eclipse虽然比NetBeans更快、响应更快,但使用起来仍然很笨拙,感觉不是很原生。Swing虽然速度较慢,但每个版本都在进行改进。我粗略统计了根据关于AWT和Swing的书籍、论坛和博客文章的数量,估计Swing社区比SWT的社区群体大得多。Swing/AWT曾经是(现在仍然是)唯一包含在Java中的工具包,你可以构建一个完整的GUI应用程序,而不需要任何第三方依赖项,Java运行时环境大不相同。
尽管我还没有在实际项目中使用过SWT,但它的存在让我感到欣慰。这些年出现了一些不支持Swing的替代JVM2,并且一直是在此类平台上编写GUI应用程序的一种快速方法。
据我所知,在2000年初的AWT、Swing和SWT是用于跨平台JavaG UI开发的唯一选择。而Java FX直到2007年才出现。
Java Cocoa Apps
大约在那个时候,Apple公开宣布他们将采用Java作为Mac OS X上的一等公民。Java将预装在 OS X中,并且赋予Swing一个Native Mac主题,让它们的外观和使用感觉就像一个原生应用程序。这意味着你可以将Java应用程序交付给Mac用户,而且可以保证它能够运行。
他们还提供了将Java应用程序捆绑为原生OS X .app的工具,让你可以将Java应用程序作为一个真正的原生应用程序发布。如果你足够严格地遵循Mac用户界面指南,用户甚至不会意识到这些应用程序是用Java编写的。
不幸的是,大多数Swing应用程序的开发人员没有遵循Mac UI指南,因此用户在使用Java应用程序时仍然会觉得有些东西“不对劲”。比如,在应用程序中,菜单项可能出现错误的加速键,或者完全缺少标准菜单。事实上,要让Swing UI在Mac上感觉完全原生,需要做很多工作。
与原生Mac UI工具包Cocoa不同,Cocoa提供了一个完全原生的应用程序外壳,并以菜单作为起点,Swing应用程序从零开始。你必须从头开始创建自己的窗口和菜单,除非你使用的是框架——而且我还从来没有见过一个Java框架可以提供完全原生的Mac应用程序体验。
但是,Apple又为Cocoa提供了Java绑定,这样Java应用程序不仅仅是看起来像一个原生应用程序,它实际上就是一个原生应用程序。在这种情况下,你在Xcode中创建一个新的Cocoa项目,并选择Java作为项目的语言,然后它会提供本机应用程序外壳作为起点。当你按下“构建”时,它会生成一个完全原生的应用程序,你可以将它发送给你的用户。
我用这个Cocoa bridge写了一些示例应用程序,并且非常完善。但是由于这类应用仅限于Mac,所以被Java社区中的WORA狂热者所淘汰,加上“原生”mac开发社区对使用Java并不感兴趣,留下的文档很少。如果你想使用Cocoa-Java桥接器,必须熟练地将Objective-C代码示例转换为它们的Java等价物。这很麻烦,所以可想而知,Apple仅在几年后(2005年)就退出了Cocoa-Java桥。再然后,Apple对Java失去了兴趣。要是你对用Java编写Cocoa应用程序感兴趣,可以去了解一下Rococoa项目。
总结
这段历史并不全面,也不是按时间顺序写的。因为我讲述的是我自己在Java桌面环境中的旅程,所以会更侧重于Mac(因为自从我拥有了第一台Mac Classic之后,我就一直是Apple用户)。
我认为2005年可以说是Java在桌面上的转折点。在2005年之前,网上论坛上有很多关于Java桌面技术的问答,比如Swing、Cocoa Bridge等。2005年之后,真的不多了。很多Java桌面的开发员可能转移到服务器端,而留在客户端的人可能会将注意力放在Web或本地开发上。
你对Java的桌面开发历史有什么看法呢?欢迎在下方留言。
《新程序员001-004》全面上市,对话世界级大师,报道中国IT行业创新创造