將會生成如下個項目 HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Plug
in
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment
同時
Java
SDK安裝程序將會把java
exe
javaw
exe
javareg
exe這
個可執行文件拷貝到winnt\system
目錄下
由於winnt\system
被操作系統缺省的設置為最高優先權的PATH搜索路徑
因此可保證用戶在命令行任何目錄下可運行java
exe來啟動JVM
那麼java
exe在啟動時如何確定其JRE所在的目錄以及需要動態加載的鏈接庫呢?java
exe是通過下面方式來確定的
假如存在
/jre/bin/java
dll文件
則查找
/jre/lib/ jvm
cfg文件
在該文件中
第
個被列出的jvm
dll類型作為缺省值(假如在java
exe命令行指定了jvm
dll的類型
則使用指定類型)
jvm
dll類型分為hotspot
classic
server三種
假如不存在
/jre/lib/jvm
cfg文件
則打印下面的錯誤信息
Error: could not open
c:\jdk
\jre\lib\jvm
cfg
如不存在
/jre/bin/java
dll(當運行的是winnt\system
\java
exe)
則注冊表將在此時發揮作用
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\ CurrentVersion鍵值所記錄的實際上是winnt\system
\java
exe的版本值
該版本值只保存主
次兩個版本號
如
等
同時java
exe程序內部本身也有一個標識自身的版本值
如
等
java
exe根據自己內部的版本值和CurrentVersion值相比較
如果發現兩個值相等
則將在HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\MainVersion
MicroVersion項下獲取JRE所在目錄及動態鏈接庫
這兩個鍵的名稱分別是JavaHome和RuntimeLib
MainVersion表示主版本號
MicroVersion表示次版本號
如果java
exe內部版本值和CurrentVersion不一致
則報類似以下的錯誤
Registry key
Software\JavaSoft\Java Runtime Environment\CurrentVersion
has value
but
is required
意思是說
注冊表當前所記載的winnt\system
\java
exe版本為
但是此時運行的java
exe版本為
java
exe抱怨除非注冊表有
版的記載
否則自己無法正確定位JRE目錄和jvm
dll
因此提示
是需要的
這裡
我們不能簡單的修改注冊表的CurrentVersion值來達到這個目的
一般地
當在系統中裝了兩套版本的Java
SDK(如先裝
而後又裝了
)
後面安裝的Java
SDK會將自己帶的java
exe和javaw
exe拷貝到winnt\system
目錄下
從而覆蓋先前版本的java
exe和javaw
exe
並且在注冊表中改寫CurrentVersion為
所以建議在安裝Java
SDK前
先卸載以前安裝的版本
如果人為的修改CurrentVersion
會使得不同版本的java
exe加載與己版本不符的java
dll及jvm
dll
將引起難以預料的後果!
特殊情況 JBuilder自己帶一套JDK
在JBuilder安裝完成後
JBuilder安裝程序會修改CurrentVersion為自己所帶JDK的版本
但不會覆蓋winnt\system
下的java
exe和javaw
exe
WebLogic自己帶一套JDK
在WebLogic安裝完成後
WebLogic安裝程序不會修改注冊表
也不會覆蓋winnt\system
下的java
exe和javaw
exe
Oracle自己帶一套JDK(一般是比較低版本的
例如
僅僅帶JDK
)
在Oracle安裝完成後
Oracle安裝程序不會修改注冊表
也不會覆蓋winnt\system
下的java
exe和javaw
exe
但是
Oralce安裝程序會修改系統PATH變量
將自帶的JRE的bin路徑加入其中
且置於最前面
隨著Oracle安裝版本的不同
其自帶JRE的JVM啟動程序也不同
在筆者機器上安裝的Oracle
其JRE就裝在C:\Program Files\Oracle下
並將C:\Program Files\Oracle\jre\
\bin放在PATH變量最前
其JVM啟動程序是jre
exe而非java
exe
以上就是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
中java
exe所在路徑加入到操作系統PATH的首位
從而保證在命令行調用java時總是執行JDK
中的java
exe
以使得java
exe可正確定位JRE和jvm
dll
問題 當在操作系統中安裝了JDK
而後安裝了JBuilder
(自帶JDK
)
這時CurrentVersion為
但是此
是指向的是JBuilder
自帶的JDK
的JRE
而非指向先前JDK
的JRE
當在命令行執行java
version時
此時執行的是JDK
拷貝到winnt\system
的一個java
exe副本
但打印的版本信息卻是
java version
Java(TM)
Runtime Environment
Standard Edition (build
b
)
Java HotSpot(TM) Client VM (build
b
mixed mode)
導致該問題的原因是java
exe只維護小數點後
位的版本號
而非
位
解決方法同問題 問題 如果在操作系統中先安裝了JDK
而後安裝了帶有與安裝JDK主次版本相同的JBuilder
(帶JDK
前兩位相同)
則問題
實際上被隱蔽了
沒有發生的機會
而問題
的隱蔽性也很強
不容易發覺
因為人們往往會忽略JDK的第
個版本號
如問題
所敘
在命令行執行java
雖然是使用JDK
的一個java
exe副本(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/libjava
so和
/jre/lib/sparc/libjvm
so來找到這
個文件
前者類似於Windows下的java
dll
而後者類似於Windows下的jvm
dll
所以java也總是可以確定自己JRE的目錄
Windows和UNIX上用到的動態鏈接庫
實際上在Sun的文檔中稱為optional package
s native code binaries
optional pakage實際上即為extension mechanism classes
詳見《Java
中的class定位機制》
要更改UNIX上java的版本
更改/usr/java的鏈接是其中一個方法
具體可參見JDK在UNIX上的安裝介紹
補充
(
)
Windows如何定位Plug
in
根據在PATH環境變量中找到的java
exe的版本號
到HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Plug
in下尋找對應版本的Java Plug
in
在HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Plug
in下可以有多個版本的Plug
in存在
不依賴HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit的CurrentVersion值和HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment的CurrentVersion值來定位應該使用哪個版本的Java Plug
in
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26028.html