本文提供更多的技巧,使读者能了解怎样绕开microsoft的javasdk中的错误(以及netscape的communicator补丁中存在的问题)
[摘要]在“如何避免microsoft非标准javasdk的潜在危险”这篇文章刊出之后,读者的反馈信息蜂涌而至,其中不少读者指出了microsoft的java开发工具中存在的另外一些潜在问题。本文将围绕着自前一篇文章刊出之后,读者提出的五个具体问题展开讨论,提供更多的补充。
上个月刊出的文章“如何避免microsoft非标准javasdk的潜在危险”,引来了数量相当可观的读者反馈。针对某些读者的评论,我认为有必要写一篇后继短文来帮助我们澄清几个观点。以下五个方面,是我认为需要加以说明的:
1.microsoft的应用程序基本类(afc)
2.locale的变化
3.远程方法调用(rmi)
4.动作差别
5.netscapecommunicator的java补丁。
microsoft的afc
在前面的文章中,我曾声明过,将应用程序基本类(afc)与internetexplorer4.0(ie4)和microsoft的java软件开发套件(sdk)第二版包装在一起,应当使开发者能够开发出独立于microsoftjava环境的java解决方案。对于这一点,所需要的唯一条件就是microsoft必须将afc的利用范围限制于microsoft的java虚拟机之外。在该文写出之后,microsoft曾声称,就目前而言,在短期内,它将不会装备一个包括ie4的、纯java版本的afc。然而,它将会为java1.0.2环境装备一个纯java版本的afc。一旦这种装备完成了,开发者就将会通过afc,创建交叉浏览器解决方案。值得注意的是,这两个版本的应用程序开发接口(api)将不会相同,因为与ie4和sdk装备在一起的版本不但要支持java1.1事件模式,而且还要支持1.0事件模式。我猜想,创建与这两个版本都兼容的方案是有可能的,就如java1.0的applet能够在java1.1环境中工作一样。但是,在java1.0.2版本的afc发布之前,所有的结果都不会明朗。
同样,自从上篇文章刊出之后,microsoft发布了macintosh和solaris平台的ie4的预备版。根据microsoft公司的charlesfitzgerald的说法,与这两个版本装备在一起的afc与windows环境下的ie4所带的afc可以兼容。afc的版本可以互相兼容,这就允许开发跨操作系统平台的afc解决方案,但仍不能获得跨java虚拟机(cross-javavirtualmachine)的解决方案。(hp-ux和aix版本的ie4在不久的将来也能得到。)
在此值得提一提的另一条信息是:由于afc类并不能实现系列化(“serializable”),它们不能象bean兼容工具应用javabean组件一样,被直接应用。它们目前的应用仍停留在源码级别上,而且能够在将来提供系列化功能,但是,microsoft仍未决定开发afc组件beans。
locale的变化
在前一篇文章中,谈到了locale类中新增的大约50个公共实例变量,以及在java.text.resource包中新增的支持文件。虽然locale实例变量是microsoft类库专用的,但是,给locale对象提供支持的java类,却并不是专门针对microsoft环境的。这就意味着你仍可以利用日期及文本格式支持类来支持各种locale类。但是,你不应该使用microsoft专用的常量。因此,例如,你不应当使用microsoft专用的locale.finnish常量,而应当利用newlocale("fi","fi")或newlocale("fi","")来创建一个新的locale对象。
rmi
microsoft提供了应用于其java虚拟机上的sun的rmi类,以免你丢失了上一篇文章的资源链接。这点在表面上已于今年八月就已完成,但如果你不知道查找rmi.zip,你将发现查找是十分困难的。现在,它已和其它java资源列在一起,可以从microsoft公司得到。然而microsoft并不提供任何支持,为了使用与ie4相应的类,它们必须从本地安装。任何一个想利用rmi的applet,不能从internet上下载rmi类。换句话说,rmi类必须从可靠来源获得(从本地装入)。
动作差别
许多读者指出了另外一些microsoftjava实现的动作差别,而且有的读者甚至还创建了web站点以展示与此相关的问题。在第一篇文章中,由于我主要关注的是api的差异,因此有些问题我并没有提及。在更深入地使用microsoftjava类的过程中,有些读者发现了更多的问题,这种情况我早有所料。作为一个开发者,我们应当意识到这些问题,并且在可能的情况下绕开它们。microsoft已经声明,有些差别已被当作bug,并且加以了改正。在被改正的jvm发布之前,了解这些问题是有好处的,至少你不必不知所措地去到处乱找错误的来源。
untrustedapplets及框架中的菜单显示
被读者指出的第一个问题与untrustedapplet被打开时框架中的显示菜单有关。这一错误可以在http://www.sc-systems.com/public/misc/ie4menubug/这一地址看到。在ie4中,一个untrustedapplet的警告信息看来占据了框架用于显示菜单条的空间,然而当用netscape浏览器和internetexplorer3.0时,它却显示正常。尽管这个测试显示的是在特殊情况下ie4可能出现的错误,但ie4中用于显示和测定框架大小的方法是不标准的。大多数的读者利用setsize()和setvisible()来显示框架时,不可能遇上这种错误。而相反的是,频繁调用addnotify(),setsize(),并接着调用setvisible()的开发者将会遇上麻烦。你不必直接调用addnotify()以创建一个组件的同位类(peer)。如果一个程序需要用到只有同位类才能提供的信息,则可以重载addnotify()方法,先让这个新的方法调用super.addnotify(),再在这个重载的方法中,利用由super.addnotify()获得的信息。
利用ie和socks代理服务器
读者所指出的第二个问题与ie利用socks代理服务器的配置有关。如果ie被配置成利用socks代理服务器方式,那么从“jview”(sdk的java命令行载入程序)启动的java应用程序将利用这个代理服务器。如果本地的防火墙不知道internet的网络配置,那么当socks服务器查询本地主机的地址时,它执行这个查询,认为它与通常的internet名字空间不相符,因而失败。很名显,microsoft实现抽象的socketimpl类,以及对私有的plainsocketimpl类的进行包装时,先搜索windows的注册信息,并利用代理服务器主机作为主机名字解析。一但失败,与microsoft虚拟机捆绑在一起的socket存取就会抛出一个socketexception异常。但在jdk和netscape环境下,这些工作都是正常的。想得到此问题的更完全描述,可参见http://www.findmail.com/listsaver/advanced-java/4873.html。
有一个方法可以绕过这个问题,但是请记住,这个问题对于microsoft最新的ie4和javasdk版本来说,并不是一个新问题。ascenttechnology的sundarnarasimhan,一个分布式软件开发者,提供了下面的方法:通过下面的一段代码,删除“socksproxyhost”系统属性,以避免用到socks代理。
propertiesp=system.getproperties();
if(system.getproperty("java.vendor").equals("microsoftcorp.")){
p.remove("socksproxyhost");
}
编译差异:sun的javac和microsoft的jvc
我们碰到的第三个问题与javacjdk编译器和jvcsdk编译器二者之间的动作差别有关。当一个内嵌类存取一个外部类的私有变量时,sun的java编译器对这种情况的处理,不同于microsoft的编译器。这看起来意味着,当创建跨java系统方案时,你不应该通过内嵌类来存取其外部类的私有变量,相反的是,你应该或者为这个变量创建一个存取例程,或者将这个变量变成包私有变量。
还发现的其它问题:
toolkit.beep()在untrustedapplets中不允许使用
list.setforeground()/setbackground()这两个方法被省略
有关netscape的问题
在有关netscape的小问题中,我已提到过netscape通过其communicator补丁,对其java类库的改变──及这些改变可能带来的一些麻烦。sun已经了解到这些问题,而且netscape也已签署了一个协议,保证在最终版本的发布前,改正这些错误。在最终版本的发布之前,如果你利用了netscape的visualjavascript工具(当前它仍还是beta版本),借助javabean来创建解决方案,那么你就会用到javascript的非标准的java扩充。这意味着,由visualjavascript工具创建的程序,可能在communicator环境之外不能工作。与对付microsoft的专有扩充一样,在这些问题被改正之前,避免使用netscape的专有扩充。
结论
在对microsoft的javasdk和ie4作了更进一步的考查之后,我的结论没有改变。当你想创建一个跨java平台的实现方案时,如果利用了microsoft最近推出的新版本,你就可能发现这一工作变得更加困难。afc仍然不是一个跨平台的实现,而且我们不可能在很短的时间内,得到它对javabeans的支持,尽管java1.0.2版本的afc发布即将来临。同样地,如果只用于microsoft环境,locale常量的增加就不会象最初所说的那么麻烦,而从microsoft公司,你也可以得到rmi类。
的确,在microsoft的java实现中,存在着动作差别。每个人都希望在一个版本推出之前,更多的象此类的问题和差别能够得到解决。由于面临最基本的问题,可以看得出,microsoft已经能够对开发者所关心的问题作出更为积极的响应。对于javasoft,microsoft已经提供了付款支持服务(如果这个问题最终被认明是bug,则将不收取技术支持费用。)最后,值得一提的是,microsoft在10月未发布的java环境修订版中,对前面所说的菜单和toolkit.beep()bug都做出了修正。这个版本还增加了最初版本中遗漏了的bytearrayoutputstream方法。如果你还被这些问题困绕的话,你可以在http://www.microsoft.com/java/vm/vmdownload.htm页面下,下载这一新的版本。
资源
microsoft的javasdk2.0
http://www.microsoft.com/java/sdk/20/relnotes/intro.htm
microsoft的afc
http://www.microsoft.com/java/afc/
java不兼容性检测代码
http://www.endware.com/twm/nojava/noj-dev.htm
microsoft提供的应用于microsoftjava虚拟机的sun′srmi类
http://www.microsoft.com/java/resource/misc.htm
davidcarr′的文章
http://www.webweek.com/1997/10/20/news/19971020-java.html
有关ascenttechnology的信息
http://www.ascent.com
内嵌类对封装它的类的私有成员的存取
http://www.microsoft.com/java/sdk/20/tools/jvcread.htm
microsoft的付款支持页面
http://www.microsoft.com/java/sdk/20/support.htm
闽公网安备 35060202000074号