CSDN博客

img moli

Inside Java2 SDK Source Internal 深入Java2 SDK原始码(一) Java2 SDK原始码概观

发表于2002/4/20 15:58:00  1204人阅读

Inside Java2 SDK Source Internal
深入Java2 SDK原始码(一)
Java2 SDK原始码概观

王森
台湾交通大学科技管理研究所
moli.mt88g@nctu.edu.tw


█前言

    到目前为止,Sun Microsystems的网站上只释出了Java2 SDK 1.3 Win32版本的原始码,而Java2 SDK Solaris/Linux版本的原始码最多只到1.2.2。因此本文内容只适用于Java2 SDK 1.3的Win32版本原始码。所有的操作皆在Windows 2000 Professional操作系统上经过测试。如果您在不同的平台上验证本文内容,或是使用将来释出的Solaris版本、Linux版本的原始码。我们无法保证会有相同的结果。

█简介

    据说信息社会的演进有个lifecycle,从早期每个人的办公桌上只有一部终端机的时代慢慢进步到PC时代,然后我们发现逐渐地潮流又走回NC(Network Computer),厂商鼓吹thin client的时代。对于原始码的看法亦是如此,从早期厂商在出售的机器内附上程序原始码供顾客自行修改,然后渐渐地程序代码变成厂商独有而不愿公开的资产,最后又演变成大家鼓吹Open Source、Free Software的时代。姑且不论普罗大众是否真的有兴趣去trace附在您计算机之中的原始码,但是我想这就是开放原始法最可贵的地方 – 大家都有机会一窥系统的内部行为,自己计算机上资料的安全以及程序的运作方式再也不会掌控在特定厂商的手上,有了原始码,我们在也不用怀疑是否某个厂商的操作系统或是应用程序会偷偷地在背后将您的资料回传到他们公司的服务器中。
     随着这股开放原始码的潮流,Java2 SDK的原始码其实已经release出来很长一段时间了,但是采用的License为Sun Community Source Code License(SCSL),与一般我们讨论到Open Source时所会提到的General Public License(GPL)有所不同。相信最近大家会发现,在相关文章中也开始提及将Java SDK改用General Public License释出的议题。当今年10月Sun将Star Office的原始码以General Public License释出之后,接下来大家所期待的就是Sun将Java SDK的原始码以General Public License释出,如果此事成真,那幺Java今后的发展将不是我们目前所能预测的,如果成功,那幺Java会像Linux一样展翅高飞,如果没有成功,那幺将可能像Mozilla计划一般雷声大雨点小。
     先姑且不论哪个License比较open,哪个比较free,笔者撰写此系列文章的目的只有一个,就是挖掘出存在于Java2 SDK内部的运作机制。由于笔者从事Java的教育工作已有一段时间,教过的学生越多,越是深感自己对Java的认识仍然有限,举凡我们常用的执行档(exe,例如javac.exe、java.exe等)、几个重要的动态连结函式库(dll,例如jvm.dll、java.dll等),以及其它使用Java程序语言所撰写的套件(package,例如java.io、java.util等),这些都是我想认真去了解的课题,因而有本系列的诞生。
    当然,trace别人的程序代码这种事情乍看之下有点像是程序黑手在做的事情,但是笔者深深觉得,台湾的软件工业要站上国际舞台仍然需要很长一段时间。从大观点来看,系统分析、系统设计、系统测试、如何妥善地分配有限人力这些议题上,至少我们还没有办法举出哪些国内公司将这些工作做的十分出色,从Java2 SDK的原始码结构中,我们可以看到开发一套SDK(Software Development Kit)时采用的团队组织架构之缩影,原始码的位置怎幺放? 那幺多程序设计师写出来的程序如何整合在一起发挥纵效? 如何让文件的产生自动化? 我想我们一定可以从Java2 SDK的原始码得到一些答案。从小观点来看,如何善用Design Pattern? 如何写出有效率的程序代码? 如何让程序设计师写出来的程序代码具有一致性? 我们都知道Java内部的套件大量地使用了Design Pattern,我们也知道Java因为虚拟机器的关系,所以程序代码必须非常地有效率,相信这些问题也能够从Java2 SDK的原始码获得答案。
    大力推展Open Source的开发中国家也非常清楚,开放原始码将是开发中国家赶上已开发国家软件工业的终南快捷方式。期待个人的努力可以成为这个大革命中一颗不可或缺小螺丝钉。
    在本系列的第一篇中,笔者将介绍Java2 SDK原始码的概观,先让读者具有取得Java2 SDK原始码并能够成功编译这些原始码的能力。废话不多说,让我们开始吧! 

█如何取得Java2 SDK 原始码

     要取得Java2 SDK的原始码,首先您必须要是Java Developer Connection(JDC)的一员,所以请您先到http://developer.java.sun.com/developer/网站上注册,取得使用者ID和密码。如下图所示:

    当您成功成为Java Developer Connection(JDC)的一员之后,请您到http://www.sun.com/software/communitysource/java2/,您将会看到下载Java2 SDK原始码的选项,点选进去之后,输入您在Java Developer Connection(JDC)的使用者ID和密码,确认您接受License之后,就可以开始下载Java2 SDK的原始码。如下图所示:

█Java2 SDK 原始码之架构

    当您解开Java2 SDK原始码的压缩档之后,您会看到如下图所示的目录结构:

  • build目录
        放置了所有的makefile档,这些makefile为Visual Studio内附的nmake.exe所能解读的格式。通常makefile的档名有五种,分别是Makefile、*.nmk、*.jmk(指定要编译的 .java檔)、*.cmk(指定要编译的 .c檔)、*.mk。在build/share底下您还可以找到一些 .java檔。
        由于我们要编译的是Windows操作系统下的Java SDK,所以Makefile的主档为build/win32/Makefile,整个Java2 SDK的编译流程都是根源于这个档案,在build/win32/makefiles目录之下您可以找到共享的Makefile,通常附档名为 .nmk。
        build/win32目录下的makefile都是用来建造和Windows操作系统相关的程序。而在build/share目录底下就多为 .mk、.jmk、.cmk档,这些档案通常用来建造和Windows操作系统无关的程序。
                  

  • ext目录
        这个目录底下放置了用来支持Java2 SDK函式库的makefile与原始码,这些原始码皆使用Java程序语言所撰写。
        ext/i18n目录下放置了与国际化(internationalization)相关的函式库,这些编译过的档案最后都被放到i18n.jar里头。
        ext/jpda目录下放置了与Java平台除错器架构(Java Platform Debugger Architecture)相关的档案。
         

  • src目录
        这个目录放置了所有建构Java SDK所需要用到的 .c文件(以C程序语言撰写)以及 .java文件(以Java程序语言撰写)。
        src/win32目录下都是用来建造和Windows操作系统相关的原始码。而在src/share目录底下就多为与Windows操作系统无关的原始码。因此聪明的读者们应该可以猜到大部分Java标准套件的原始码大多放在src/share目录之下。这些标准套件的原始码在最后都被加入到src.jar之中,而编译过的 .class档则被打散放入许多不同的jar档内。

  • LegalReadme.html
        Sun Community Source Code License版权宣告
         

  • OriginalCode.txt
        Java2 SDK原始码中所有档案的列表。
             

  • README.html
        关于Java2 SDK原始码的说明,该内容大部分都已经被笔者吸收而整合到这篇文章之中。

        从Java2 SDK原始码的架构中,我们可以发现其档案的放置方法很独特,是采用makefile与原始码分开放置的做法,不同于一般我们所见(例如Linux kernel原始码)采makefile和原始码放在一起的做法。这两种做法各有利弊。以Linux Kernel原始码的做法,每次编译完成之后,您将看到原始码档案和编译过程中产生的中间档混杂在一起,感觉有点混乱。如果我们采用Java2 SDK原始码的目录结构,每次编译出来的中间档和原始码就会分隔在不同的目录下,看起就非常赏心悦目,但是,这样放置的代价就是makefile里头对于路径的参照变得十分复杂,您将会在Java2 SDK原始码的makefile中发现很多 ../../../src 的叙述,看起来真是不舒服,如果我们要了解该执行档是由哪些档案构成的时候就很辛苦了。

█如何编译Java2 SDK 原始码

    当我们深入了解Java2 SDK原始码之后,很多工程师必定想自己尝试修改原始码,然后进行编译,我想这是身为一个工程师最大的乐趣。当然,在我们还没有修改之前,我们也必须试着编译整个原始码,顺便测试一下原始码是否完整,因此接下来要介绍编译Java 2原始码的准备步骤和方法。
要顺利编译Java2 SDK原始码,您必须符合底下几种条件:

  1. 操作系统
        您必须在Windows NT 4.0或是Windows 2000上才能顺利编译Java 2原始码。一旦编译完成之后,所产生的执行文件或是动态连结和式库将能够在所有的Win32作业平台上执行。
        

  2. 硬设备
        在Java2 SDK原始码内附的文件之中,建议的硬设备为Pentium等级的处理器,配上至少128 MB的内存。在笔者的计算机上,Pentium III 450配上PC 100 128 MB 的内存,总共花了将近2.5个小时完成所有编译动作。如果算上编译时期遇到的一些错误以及恢复错误的时间,大概花了3个小时。
        

  3. 开发工具
        我们必须准备几项工具,他们分别是:

    • Microsoft Visual C++ version 6.0,并配上最新的Service pack(或者Visual Studio 97配上Service Pack 3)。
          在Java2 SDK原始码之中,存在有许多与Windows平台相关的程序代码,这些程序代码都以C语言撰写而成,为了顺利编译这些原生程序代码,我们必须要借助Visual C++编译器以便产生能在Windows平台上执行的执行档(.exe)以及动态连结和式库(.dll)。
          同时,Java2 SDK原始码之中有许多Makefile,这些Makefile是用来控制所有程序的编译动作。我们必须借助Visual C++内附的nmake.exe这个工具以帮助我们解读这些Makefile并顺利编译出整个Java2 SDK。
    • MKS Toolkit version 5.2以上的版本。
          MKS Toolkit是一套能够在Windows上仿真UNIX执行环境的工具,请到http://www.mks.com下载这套工具的30天试用版(正式版必须要付费)。或者如果您有订阅MDSN Profession以上的版本,您可以在光盘中找到Microsoft Windows Services for UNIX 2.0 Add-On Pack(在UNIX20_INSERV/3RDPARTY/MKS目录底下,执行x86子目录中的setup.exe即可安装)。30天试用版的功能骑士和付费版本的功能一样,只不过当您在编译Java2 SDK原始码的时候,只要用到了MKS Toolkit里的工具,就会出现一个广告画面罢了,应该不会影响您的心情才是。
    • Java2 SDK 1.3的可执行版本。
          相信读者们看到这个地方,一定会觉得很疑惑。奇怪,编译Java2 SDK的原始码竟然也需要Java2 SDK的协助? 不禁让人想起鸡生蛋蛋生鸡的问题,不是吗? 其实Java2 SDK在整个编译过程中,扮演的是bootstrap compiler(靴带式编译器)的角色。之所以需要Java2 SDK的原因是因为大家在编译Java程序时所使用的javac.exe核心程序竟然也是用Java撰写而成的,由于Java2 SDK的原始码有许多与平台无关、以Java程序语言所撰写的程序,因此在编译初期,我们必须借助过去旧版的Java2 SDK或是JDK帮助我们产生新版的Java2 SDK,再利用新产生的新版javac.exe编译Java2 SDK原始码内的其它 .java檔。

    当大家将所有必备的条件都准备妥当之后,接着我们要开始准备编译前的相关工作。底下的内容将有下列假设:

工具

安装路径

Windows NT/2000系统所在目录

c:/winnt

Microsoft Visual C++ version 6.0

d:/Microsoft Visual Studio

Microsoft Visual Studio 97

d:/Program Files/DevStudio

MKS Toolkit

c:/mskdemo/mksnt

Java2 SDK 1.3的可执行版本

d:/jdk1.3

Java2 SDK 原始码

d:/jdk1.3-src

    接下来我们要设定环境变量,为了方便起见,请大家新增一个叫做env.bat的批次档,这样以后要修改环境变量的时候就不必大费周章:
如果您使用的C编译器为Microsoft Visual C++ version 6.0,那幺env.bat的内容如下:
env.bat

set MSVCDir=d:/Microsoft Visual Studio/vc98
set MSDevDir=d:/Microsoft Visual Studio/Common/MSDev98
set WinDir=c:/winnt
set include=%MSVCDir%/include;%MSVCDir%/mfc/include;%MSVCDir%/atl/include
set lib=%MSVCDir%/lib;%MSVCDir%/mfc/lib
set PATH=c:/mskdemo/mksnt;%MSVCDir%/bin;%MSDevDir%/bin;%WindowsDir%/system32;%PATH%
set ALT_BOOTDIR=d:/jdk1.3
set TMPDIR=d:/jdk1.3-src/tmp

    如果您使用的C编译器为Microsoft Visual Studio 97,那幺env.bat的内容如下:
env.bat

set MSVCDir= d:/Program Files/DevStudio/VC
set MSDevDir= d:/Program Files/DevStudio/SharedIDE
set WinDir=c:/winnt
set include=%MSVCDir%/include;%MSVCDir%/mfc/include;%MSVCDir%/atl/include
set lib=%MSVCDir%/lib;%MSVCDir%/mfc/lib
set PATH=c:/mskdemo/mksnt;%MSVCDir%/bin;%MSDevDir%/bin;%WindowsDir%/system32;%PATH%
set ALT_BOOTDIR=d:/jdk1.3
set TMPDIR=d:/jdk1.3-src/tmp

    任何一个环境变量设定有误,都会造成编译错误,请读者们务必小心。关于环境变量,底下有几件事情请读者一定要注意:

  1.     对于PATH环境变量来说,MKS Toolkit的路径一定要出现在Microsoft Visual C++ version 6.0(或是Microsoft Visual Studio 97)的所在路径之前,否则会造成编译错误。所以请不要将PATH设定为:set PATH=%MSVCDir%/bin;%MSDevDir%/bin;c:/mskdemo/mksnt; %WindowsDir%/system32; %PATH%(MKS Toolkit出现在Microsoft Visual C++ version 6.0(或是Microsoft Visual Studio 97)的所在路径之后)
  2.     请关闭CLASSPATH环境变量。如果您是在Windows 2000底下,请在”我的计算机”图标上按下鼠标右键,选择”内容”,点选”进阶”次页,再按下”环境变量”按钮。将出现环境变量对话框,如下图所示:

        请寻找使用者变量中或是系统变量中任何名为CLASSPATH的环境变量删除,否则在编译Java2 SDK原始码初期就会出现错误讯息。
  3.     环境变量ALT_BOOTDIR是用来设定bootstrap compiler(靴带式编译器)的所在位置,您只要设定为Java SDK的安装位置就可以了。

    当上述准备工作全部完成之后,请开启”命令提示字符”窗口(就是DOS窗口啦!),并将目录切换到d:/jdk1.3-src/build/win32底下,在命列上输入 nmake world 此时编译Java2 SDK原始码的过程正式展开,毫无疑问地,这将是一个漫长的过程。
    在编译的过程之中,在笔者的计算机上出现了一些编译错误,在这里顺便向各位提及,顺便说明笔者的解决办法:

  • 找不到 .properties檔:
        在编译Java2 SDK原始码的时候常常出现找不到 .properties文件的错误讯息,如果发现编译终止的原因是因为在个特定目录底下找不到某个 .properties档,那幺请读者自行搜寻 jdk1.3-src/src目录底下,一定能找到编译器所找不到的 .properties档,请将这个 .properties档复制到编译器期望该档案所在的目录底下即可解决。
  • 找不到 .class檔:
        在编译Java2 SDK原始码初期的时候常常出现找不到 .class文件的错误讯息,笔者发现这些找不到的类别档都是放置在jdk1.3-src/ext/i18n/src/share/sun/io/底下,之所以会找不到这些.class档的缘故是因为根据Makefile里头的内容,jdk1.3-src/ext目录里的原始码会较晚编译,而我们又关掉了CLASSPATH环境变量,导致在需要这些档案的时候,这些档案尚未从 .java档编译成 .class档,很自然地编译器就无法编译。要解决这个问题,请读者们先行到jdk1.3-src/ext/i18n/src/share/sun/io/底下,输入javac *.java以产生所有需要的 .class档,然后将这些新产生的.class档复制到jdk1.3-src/build/win32/classes/sun/io这个目录底下。这样一来,就再也不会遇到找不到 .class文件的错误讯息了。
  •     Java2 SDK原始码的内附文件中要我们设定环境变量TMP,但是实际的测试结果,发现在这个路径似乎在编译过程中一点用处也没有,反倒是编译的时候有用到环境变量TEMP所指向的目录(在Windows 2000底下这个环境变量被设定为 %USERPROFILE%/Local Settings/Temp),不知道是不是写说明档的人不小心漏打字。

    当编译工作告一段落之后,您将可以在jdk1.3-src/build/win32目录下找到所有编译过的执行档以及 .class档,还有一些编译过程中产生的中间档。
    jdk1.3-src/build/win32/bin目录下,您将会看到所有让Java2 SDK正常运作的执行文件以及动态联结函式库。又由于我们是使用make world指令,如果您观察一下这个目录,您会发现每个档案都有最佳化版本与除错版本(ex: java.exe与java_g.exe,其它以此类推)。
    jdk1.3-src/build/win32/lib目录下将放置所有让Java程序能够顺利执行的套件函式库,例如i18n.jar等,在jdk1.3-src/build/win32/lib/ext目录下可以找到iiimp.jar等扩充套件还有一些资源档。
    jdk1.3-src/build/win32/classes目录下放置了最后会压缩成rt.jar的所有 .class檔(类别档)。

    另外,除了输入 nmake world 指令之外,Makefile之中定义了其它非world的编译选项,请参阅下表:

编译指令

作用

nmake all

 

建立Java SDK核心程序的除错版本以及最佳化版本

 

nmake ext

建立Java SDK扩充程序的除错版本以及最佳化版本

nmake world

(nmake world-all)

建立allext中所有的程序

nmake releasedocs

执行javadoc.exe以产生Java SDK说明文件

nmake alldocs

执行javadoc.exe以产生在sun.*套件之下程序的所有说明文件

Nmake world-clobber

删除前一次编译之后产生的所有档案和目录

    如果您想要了解所有的选项,请您自行开启jdk1.3-src/build/win32/Makefile或是jdk1.3-src/build/win32/makefiles/defs.nmk这两个档案做更深入的研究。

█接下来

    有关Java2 SDK原始码的概观介绍就到这里,相信大家都已经有了坚实的基础,如果您已经是一位非常有经验的工程师,相信您已经能够随意地修改出自己版本的Java2 SDK了!
今后的文章中笔者将继续带各位深入实际的程序代码之中,让大家了解您所撰写的Java程序是如何转成byte code,然后再变成 .class檔;笔者也会带大家了解 .class档是如何被加载,经过了何种处理程序,最后如何被Java虚拟机器所执行。相信这些都是大相很感兴趣的议题,咱们下次见!

█网络资源

◎网站

名称

URL

Java Developer Connection

http://developer.java.sun.com/developer/

Java2原始码下载

http://www.sun.com/software/communitysource/java2/

0 0

相关博文

我的热门文章

img
取 消
img