将会生成如下个项目
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Plugin
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment
同时Java SDK安装程序将会把javaexejavawexejavaregexe这个可执行文件拷贝到winnt\system目录下由于winnt\system被操作系统缺省的设置为最高优先权的PATH搜索路径因此可保证用户在命令行任何目录下可运行javaexe来启动JVM
那么javaexe在启动时如何确定其JRE所在的目录以及需要动态加载的链接库呢?javaexe是通过下面方式来确定的
假如存在/jre/bin/javadll文件则查找/jre/lib/ jvmcfg文件在该文件中第个被列出的jvmdll类型作为缺省值(假如在javaexe命令行指定了jvmdll的类型则使用指定类型)jvmdll类型分为hotspotclassicserver三种假如不存在/jre/lib/jvmcfg文件则打印下面的错误信息
Error: could not open c:\jdk\jre\lib\jvmcfg
如不存在/jre/bin/javadll(当运行的是winnt\system\javaexe)则注册表将在此时发挥作用HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\ CurrentVersion键值所记录的实际上是winnt\system\javaexe的版本值该版本值只保存主次两个版本号如等
同时javaexe程序内部本身也有一个标识自身的版本值如等javaexe根据自己内部的版本值和CurrentVersion值相比较如果发现两个值相等则将在HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\MainVersionMicroVersion项下获取JRE所在目录及动态链接库这两个键的名称分别是JavaHome和RuntimeLibMainVersion表示主版本号MicroVersion表示次版本号
如果javaexe内部版本值和CurrentVersion不一致则报类似以下的错误
Registry key Software\JavaSoft\Java Runtime Environment\CurrentVersion
has value but is required
意思是说注册表当前所记载的winnt\system\javaexe版本为但是此时运行的javaexe版本为javaexe抱怨除非注册表有版的记载否则自己无法正确定位JRE目录和jvmdll因此提示是需要的
这里我们不能简单的修改注册表的CurrentVersion值来达到这个目的一般地当在系统中装了两套版本的Java SDK(如先装而后又装了)后面安装的Java SDK会将自己带的javaexe和javawexe拷贝到winnt\system目录下从而覆盖先前版本的javaexe和javawexe并且在注册表中改写CurrentVersion为所以建议在安装Java SDK前先卸载以前安装的版本如果人为的修改CurrentVersion会使得不同版本的javaexe加载与己版本不符的javadll及jvmdll将引起难以预料的后果!
特殊情况
JBuilder自己带一套JDK在JBuilder安装完成后JBuilder安装程序会修改CurrentVersion为自己所带JDK的版本但不会覆盖winnt\system下的javaexe和javawexe
WebLogic自己带一套JDK在WebLogic安装完成后WebLogic安装程序不会修改注册表也不会覆盖winnt\system下的javaexe和javawexe
Oracle自己带一套JDK(一般是比较低版本的例如仅仅带JDK )在Oracle安装完成后Oracle安装程序不会修改注册表也不会覆盖winnt\system下的javaexe和javawexe但是Oralce安装程序会修改系统PATH变量将自带的JRE的bin路径加入其中且置于最前面随着Oracle安装版本的不同其自带JRE的JVM启动程序也不同在笔者机器上安装的Oracle 其JRE就装在C:\Program Files\Oracle下并将C:\Program Files\Oracle\jre\\bin放在PATH变量最前其JVM启动程序是jreexe而非javaexe
以上就是Java SDK在Windows下安装时所做的动作这样会带来兼容性问题
问题背景安装Java SDK后安装了JBuilder未修改任何PATH变量
问题
当在操作系统中安装了JDK 其后安装了JBuilder(自带JDK )这时CurrentVersion为在命令行执行java version时提示
Registry key Software\JavaSoft\Java Runtime Environment\CurrentVersion
has value but is required
解决方法将JDK 中javaexe所在路径加入到操作系统PATH的首位从而保证在命令行调用java时总是执行JDK 中的javaexe以使得javaexe可正确定位JRE和jvmdll
问题
当在操作系统中安装了JDK 而后安装了JBuilder(自带JDK )这时CurrentVersion为但是此是指向的是JBuilder自带的JDK 的JRE而非指向先前JDK 的JRE当在命令行执行java version时此时执行的是JDK 拷贝到winnt\system的一个javaexe副本但打印的版本信息却是
java version
Java(TM) Runtime Environment Standard Edition (build b)
Java HotSpot(TM) Client VM (build b mixed mode)
导致该问题的原因是javaexe只维护小数点后位的版本号而非位
解决方法同问题
问题
如果在操作系统中先安装了JDK 而后安装了带有与安装JDK主次版本相同的JBuilder(带JDK 前两位相同)则问题实际上被隐蔽了没有发生的机会而问题的隐蔽性也很强不容易发觉因为人们往往会忽略JDK的第个版本号
如问题所叙在命令行执行java虽然是使用JDK 的一个javaexe副本(winnt\system目录下)而实际上却是使用JBuilder下JDK 的JRE及其目录结构其结果是当我们使用Java的extension mechanism将jar文件放到JDK 的jre\lib\ext目录下时发现达不到希望的效果 – 在命令行用java启动程序时不会自动去JDK 的jre\lib\ext目录下去搜索jar文件它只会去JBuilder下JDK 的jre\lib\ext去搜索jar文件而JBuilder下的JDK 并不存在jre\lib\ext这么一个目录!
问题极为隐蔽除非完全对Java SDK的安装及class定位机制了解一般的开发者是难以发现问题所在的有关Java中class定位机制见《Java中的class定位机制》一文
事实上即使仅仅在系统中存在一份JDK 如果在命令行运行java的话使用的JRE目录是C:\Program Files\JavaSoft\JRE\也就是说即使我们在c:\jdk\jre\lib\ext下放置我们的extension jar也得不到预期的结果正确的做法是放在C:\Program Files\JavaSoft\JRE\\lib\ext目录下
解决方法同问题
综上所叙强烈建议将%JDK_HOME%\bin目录放在Windows操作系统的PATH变量的首位以避免潜在的问题
而在UNIX下则完全不存在类似Windows操作系统上的问题
我们在命令下执行的java是/bin/java
$which java
$/bin/java
而/bin是到/usr/bin的链接也就是说/bin/java实际上是/usr/bin/java
而/usr/bin/java实际上链接到/usr/java/bin/java/usr/java是到/usr/java的链接(Solaris 或更高系统内置JDK )所以我们实际上执行的java是
/usr/java/bin/java
根据UNIX上的情况java在运行时实际上总是可以用/jre/lib/sparc/libjavaso和/jre/lib/sparc/libjvmso来找到这个文件前者类似于Windows下的javadll而后者类似于Windows下的jvmdll所以java也总是可以确定自己JRE的目录
Windows和UNIX上用到的动态链接库实际上在Sun的文档中称为optional packages native code binariesoptional pakage实际上即为extension mechanism classes详见《Java中的class定位机制》
要更改UNIX上java的版本更改/usr/java的链接是其中一个方法具体可参见JDK在UNIX上的安装介绍
补充()
Windows如何定位Plugin
根据在PATH环境变量中找到的javaexe的版本号到HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Plugin下寻找对应版本的Java Plugin在HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Plugin下可以有多个版本的Plugin存在
不依赖HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit的CurrentVersion值和HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment的CurrentVersion值来定位应该使用哪个版本的Java Plugin