作者l314 (红虫)
看板java
标题path, classpath, jdk, jre
时间Mon Jun 25 01:16:49 2007
应板大的要求, 小弟就把文章转过来了..
有错误的部分还请大家提出,谢谢..
以下转录自小弟的blog:
http://tw.myblog.yahoo.com/l314kimo/
今天总算厘清了一些困扰我很久的东西,所以做个简单的笔记。
一、安装单一版本的jdk时,通常会有:
4个java.exe:
1.WINDOWS\system32\java.exe
2.[JRE_location]\bin\java.exe
3.[JDK_location]\bin\java.exe
4.[JDK_location]\jre\bin\java.exe
2个JRE:
1.Public JRE (指[JRE_lcation])
2.Private JRE (指[JDK_location]\jre)
前两个java.exe使用的是Public JRE,後两个java.exe使用的是Private JRE。
二、classpath无需设定rt.jar的路径,因为jdk会预设载入。(参考六)
可以在console mode 输入java -verbose得之。
(verbose 可以显示JVM会依序load哪些Class)
不知道是几版之後才如此。总之,我试了又试,有没有设rt.jar路径真的无差别,
很好奇为什麽大家都说要在classpath设定rt.jar,而我在google上却找不到答案。
也有人提倡最好少设classpath。
三、path用来设定指令的前置位址,如下:
(可以在console mode 输入set path 或 path以显示)
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;
C:\Program Files\Microsoft SQL Server\90\Tools\binn\;
C:\Program Files\Java\jdk1.6.0\bin;
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\Bin;
所以当我们在console mode 输入java XXX 时,如果current目录没有java这指令时,
便会依序尝试path下的路径。
四、jdk目录下之所以安置了一个jre,原因在於jdk下的工具大都是用java开发的。
如:java.exe , javac.exe jar.exe..等,(这些工具都放在jdk\lib\tools.jar中)
外表虽然是用RPC包装成.exe档,但其实它们都需要呼叫JRE的library。
所以JDK下就放了一个专供JDK使用的JRE,
但也可以透过path的设定让[JDK_location]\jre被一般使用者使用。
五、在console mode使用java 这指令时,它使用的是哪个jre呢?
1.先找自己的目录下是否有jre.
2.父目录底下的jre目录.(jdk\bin下的工具便是如此找到jdk\jre)
3.查询Windows Registry
(HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\)
所以这时path的顺序设定将决定采用的是哪一个jre。
case1:
若path的顺序是\WINDOWS\system32 在 \[JDK_location]\bin 之前。
java指令便是执行\WINDOWS\system32\java.exe
由於windows下无jre目录,所以会参考Window Registry下的jre。
(即前述的Public JRE)
case2:
若path 的顺序是\[JDK_location]\bin 在\windows\system32 之前。
那麽java指令便是执行C:\[JDK_location]\bin\java.exe
由於jdk下有一个jre目录,所以java会参考jdk\jre。
(即前述的Private JRE)
最常发生的问题是当path的顺序如case1,
java指令找到的jre与javac找到的jre是不同的。
产生的问题待第六点解释。
六、java找寻class的顺序
根据JDK 文件说明, java以下面3种顺序找寻class的顺序
1.Bootstrap classes
2.Extension classes
3.Users classes
Bootstrap classes指的是java在启动时载入的class,
这些class主要是rt.jar 和 jre/lib 目录下的一些class。
(所以rt.jar可以不须加入classpath)
下面列出系统中预设的Bootstrap classes:
jre\lib\rt.jar; jre\lib\i18n.jar;
jre\lib\sunrsasign.jar; jre\lib\jsse.jar;
jre\lib\jce.jar; jre\lib\charsets.jar;
jre\classes
Extension classes 指的是jre/lib/ext 目录下的jar或zip档。
third-party 的 library通常会放在这目录下,如java3d, jogl..等。
当classloader 需要resolve class时,jre会自动来此目录下找。
如果不同名字的jar,却包含了相同的class,那麽哪一个class被载入是不一定的。
第五点最後提到的问题,常常跟Extension classes扯上关系。
当我们使用third-party的library时,如果只将jar档放在Private JRE/lib/ext中,
javac指令因为使用Private JRE,所以能够找到third-party library,得以顺利compile
。
但java指令使用的是Public JRE,Public JRE找不到 third-party library,
以致无法顺利执行,原因是无法import package。
解决的方法有:
1.将third-party library jar档 在 private JRE/public JRE 各放一份。
2.设定path时,使用第五点的case2。使java及javac指都优先使用Private JRE。
Eclipse可以很方便使用third -party library,
Project->Properties->Java Build Path->Libraries->Add External JARs
User classes便是指我们在classpath设定路径下的class。
如:若总是使用c:\java\的class,或是需要使用c:\lib\test.jar里的library,
便可以set classpath =.;c:\java\;c:\lib\test.jar
(.jar档须将完整路径名加入classpath, jre才会进入该jar档里找寻target class)
user classes寻找的优先序:
(1)若无设定classpath, jre预设找(.)目前目录是否存在target class.
(2)若有设定classpath, jre只找classpath设定的路径是否存在target class.
(3)在console mode下使用-cp 或 -classpath, 则jre只找参数後的路径是否存在target
class.
(4)在console mode使用-jar来指定jar档时, jre只找寻jar中是否存在target class.
--
本文采CC授权,您可自由:重制、散布、展示及演出本着作。
但需遵照下列条件:
姓名标示及来源,您不得为商业目的而使用本着作,您不得改变、转变或改作本着作。
http://creativecommons.org/licenses/by-nc-nd/2.5/tw/
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.119.201.20