javaclasspath:Java之classpath学习来源: 发布时间:星期四, 2009年2月12日 浏览:56次 评论:0
1.搜索路径重要性 理解搜索路径对所有Java开发人员来说都很重要但是IDE广泛使用掩盖了这项技术使大家普遍对它缺乏了解甚至包括好多老鸟这个问题在开发分布式应用时尤其严重应用运行时系统环境可能和开发时大不相同 本文详细描述了某些Java类被其他代码引用时Java编译器和JVM如何使用类搜索路径定位这些类这儿用个非常简单例子——同个包中两个类——来具体介绍说明我们将通过区别方式来编译这两个类根据path设置区别编译可能成功也可能失败 为了最清楚介绍说明这个问题我们将只使用命令行工具进行编译交互式开发工具有它们自己操作path思路方法这些思路方法因产品而异 至于是由Java编译器在编译时定位需要类还是由JVM在运行时来做这两种思路方法没有本质区别但编译器可以从源代码中编译需要类而JVM不行下面例子中我们用编译器来做但在运行时实现也完全类似 2.例子 本例有两个很小类:com.web_tomorrow.CPTest1 和 com.web_tomorrow.CPTest2如下所示: package com.web_tomorrow; public CPTest1 { public void (String args) { .out.prln ("Run CPTest1."); } } package com.web_tomorrow; public CPTest2 { public void (String args) { .out.prln ("Run CPTest2."); CPTest1 cpt1 = CPTest1; } } Java代码组织个最基本规则就是`package name = directory name'(“包名 = 目录名”)我们将为这两个类建立对应目录结构它们在包com.web_tomorrow中所以我们创建目录 com/web_tomorrow来存放源代码: [root] com web_tomorrow CPTest1.java CPTest2.java 在本文中我用符号`[root]'来表示存放上述结构任意目录也就是说根目录位置由你决定当然这会随安装这些文件方式区别而不样 3.基本原理 让我们来尝试用命令行工具javac来编译CPTest1.java为了完全禁止类搜索路径(以防已有设置影响本例)我们在javac上加上选项`-path ""' 作为第次试验我们先换到CPTest1.java所在目录下并且尝试用javac和文件名进行编译 cd [root]/com/web_tomorrow javac -path "" CPTest1.java 操作成功编译器能发现CPTest1.java (它就在当前工作目录下)并且CPTest1没有引用任何其他类输出文件CPTest1.在CPTest1.java相同目录下你没有给编译器任何信息让它作其它处理到现在为止直都很好现在让我们用同样方式来试下CPTest2仍然在web_tomorrow目录下执行命令: javac -path "" CPTest2.java 虽然目录还是刚才目录CPTest1和CPTest2也在相同包里这次却失败了 信息可能是这样: CPTest2.java:7: cannot resolve symbol symbol : CPTest1 location: com.web_tomorrow.CPTest2 CPTest1 cpt1 = CPTest1; ^ 这次和上次成功情况的间区别的就是CPTest2中有对CPTest1引用: CPTest1 cpt1 = CPTest1; 这次发生了什么呢?当编译器遇到对CP1Test引用时它会认为CP1Test类和当前编译CP2Test类在同个包里这个假定是正确于是编译器来寻找com.web_tomorrow.CP1Test但它没有地方可以找我们已经把类搜索路径 明确指定成了“”(也就是空) 你可能认为只要告诉编译器在当前目录下寻找就可以解决这个问题在Unix和Windows系统中“当前目录”标准符号都是个点号(.)也就是这样命令: javac -path "." CPTest2.java Fail Aga!跟刚才例子完全样现在问题是虽然CPTest1.java在当前目录下但它实现类不是CPTest1而是com.web_tomorrow.CPTest1编译器将在当前目录下寻找目录com/web_tomorrow也就是说它在目录 [root]/com/web_tomorrow/com/web_tomorrow中寻找个Java源文件或类文件它们事实上根本不存在于是出错 为了让编译器工作正常我们不能让类搜索路径指向包含CPTest1目录而是按照Java标准中`package name = directory name'规则给类搜索路径指定编译器能找到CPTest1根目录这样才能工作虽然不太好看: javac -path "../.." CPTest2.java 在考虑如何变得不难看的前看下这个例子(仍在同目录下) javac -path "" CPTest1.java CPTest2.java 尽管path为空这次却能工作这是Java编译器会在命令行中明确列出所有源代码中查找引用如果要编译同目录下多个类有种很简单方式: javac -path "" *.java '*.java'扩展为当前目录下所有.java文件列表这就介绍说明为什么次编译多个文件会成功而同样文件个个编译却失败 编译CPTest2有个更方便思路方法: cd [root] javac -path "." com/web_tomorrow/CPTest2.java 这次我们为CPtest2.java指定了完整路径而在-path选项中使用了'.'另外我们没有告诉编译器在当前目录下寻找文件而是让它从当前目录开始搜索 我们要找类是com.web_tomorrow.CPTest1编译器将在./com/web_tomorrow(也就是说当前目录下com/web_tomorrow子目录)下寻找这才是CPTest1.java正确位置 事实上尽管我在命令行只指定了CPTest2但事实上CPTest1同时也会被编译编译器在正确位置找到这个.java文件但它不能判定这个.java文件是否包含正确类所以它编译这个文件但请注意如果是: cd [root] javac -path "." com/web_tomorrow/CPTest1.java 就不会导致CPTest2.java被编译编译器编译CPTest1时不需要知道CPTest2任何事情 类文件和.java文件分开情况 到目前为止所有成功例子都把输出.文件放到.java文件同样位置这是种比较简单模式应用非常广泛但很多开发者喜欢把源文件和生成文件分开因此它必须告诉编译器为.文件维护区别目录下面我们来看看这对类搜索路径有何影响 首先我们删除刚才几个例子产生所有.文件我们还要有个新目录来存放生成.文件命令行方式下操作过程如下: cd [root] rm com/web_tomorrow/*. mkdir es 如果你用Windows系统别忘了把'/'替换成'\'现在目录结构如下: [root] com web_tomorrow CPTest1.java CPTest2.java es 现在编译CPTest1.java指定类文件目标目录(通过-d选项) cd [root] javac -d es -path "" com/web_tomorrow/CPTest1.java 成功但你会注意到.文件根本不是直接放在es目录中而是有了个新目录结构: [root] com web_tomorrow CPTest1.java CPTest2.java es com web_tomorrow CPTest1. 编译器建立了个符合包结构目录结构这很有用我们马上就会看到当开始编译CPTest2.java时我们有两个选择第种是像上面样让编译器同时也编译次CPTest1;另种是用-path选项指定刚才编译好.文件这种思路方法更好点我们不必再来编译遍CPTest1: cd [root] javac -d es -path es com/web_tomorrow/CPTest2.java 完成的后我们目录结构如下: [root] com web_tomorrow CPTest1.java CPTest2.java es com web_tomorrow CPTest1. CPTest2. 当然我们也可以在同条命令中编译两个.java文件结果完全相同 4.path中JAR打包文件 Java编译器和运行环境不仅可以在独立文件中搜索类还可以在JAR打包文件中进行查找个JAR打包文件可以维护它自己目录结构Java按照跟普通目录结构完全相同方式`directory name = package name'进行搜索由于JAR本身就是个目录所以在类搜索路径中包含JAR打包文件时路径必须引用JAR本身而不是它所在目录如果我在目录/myes下有个JAR myes.jar我需要指定:javac -path /myes/myes.jar ...而不仅仅是目录myes 5.多个类搜索目录 在上面例子中每次我们都只让javac在个目录下搜索实际工作中你类搜索路径会包含很多目录和JAR文件Javac-path选项允许指定多个位置但请注意它具体语法在Unix系统和Windows系统中稍有区别 在Unix系统中是: javac -path dir1:dir2:dir3 ... 而Windows系统则是: javac -path dir1;dir2;dir3 ... 这是Windows使用冒号(:)作为文件名部分因此不能作为文件名分隔符当然目录分隔符也不样:Unix正斜杠(/)和Windows反斜杠(\) 6.系统path 除了在javac命令指定类搜索路径外我们还可以使用'系统'类路径如果命令中没有指定特定路径Java编译器和JVM都使用系统路径在Unix和Windows系统中系统路径都通过环境变量设置 例如在使用bash shellLinux系统中: CLASSPATH=/myes/myes.jar;export CLASSPATH 在Windows中: CLASSPATH=c:\myes\myes.jar 这是暂时改变系统变量CLASSPATH好思路方法但如果你想这些变化直保留下来你就需要针对你系统做些修改例如在Linux系统中我会将这个命令放到我目录下文件.bashrc中而在Windows 2000/NT中可以通过‘控制面板’来修改 如果你有很多随时用到JAR设置系统变量CLASSPATH就显得尤为重要比如说如果我在用SunJ2EE参考实现开发EJB应用所有EJB相关类都发布在个叫做“j2ee.jar”JAR打包文件中我希望这个JAR直都在类搜索路径中另外还有很多人希望无论当前目录是什么搜索路径始终包含当前目录所以在我.bashrc文件中就有这样行: CLASSPATH=/usr/j2ee/j2ee.jar:.;export CLASSPATH 其中`.'是指'当前目录' 很容易看到命令行中-path选项覆盖默认系统类路径;它不是扩展而是覆盖因此如果我们既要包含默认系统路径又要增加些时如何处理呢?我们可以简单通过-path选项同时列出默认值和我们要额外增加部分而个更好办法是引用系统变量CLASSPATH当然这个语法对Windows系统和Unix系统是区别 在Unix上: javac -path $CLASSPATH:dir1:dir2 ... 其中$CLASSPATH扩展为系统变量CLASSPATH在Windows上: javac -path %CLASSPATH%;dir1:dir2 ... linux下PATH和CLASSPATH设置 、、安装JDK 从sun网站WebSite上直接下载JDK:http://java.sun.com/j2se/1.4.2/download.html 提供了两个下载: 1、RPM in self-extracting file (j2sdk-1_4_2_04-linux-i586.bin, 32.77 MB) 这个是自解压文件在linux上安装如下: # chmod u+x ./j2sdk-1_4_2_04-linux-i586.bin# ./j2sdk-1_4_2_04-linux-i586.bin 在按提示输入yes后jdk被解压到./j2sdk1.4.2_04目录下为和下面2中JDK安装路径致我们进行下列操作,在/usr/java下建立安装路径并将文件考到该路径下: # mkdir /usr/java# cp -fr ./j2sdk1.4.2_04 /usr/java 2、 RPM in self-extracting file (j2sdk-1_4_2_04-linux-i586-rpm.bin, 32.77 MB)这个也是个自解压文件不过解压后文件是j2sdk-1_4_2_04-linux-i586-rpm包执行rpm命令装到linux上就可以了安装如下: #chmod u+x ./j2sdk-1_4_2_04-linux-i586-rpm.bin# ./j2sdk-1_4_2_04-linux-i586-rpm.bin# rpm -ivh j2sdk-1_4_2_04-linux-i586-rpm 安装软件Software会将JDK自动安装到 /usr/java/j2sdk1.4.2_04目录下 2、配置环境变量 1.修改用户环境变量 假设使用java用户为 kunp编辑该用户.bashrc文件进行环境变量设置 # vi /home/kunp/.bashrc 在 .bashrc文件中加入: export JAVA_HOME=/usr/java/j2sdk1.4.2_04export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/libexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOMR/bin 2.修改所有用户环境变量 # vi /etc/profile 在该文件中加入: export JAVA_HOME=/usr/java/j2sdk1.4.2_04export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/libexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin 如果是以root身份登陆只用做第 2步就可以了它已经包含了第步设置呵呵 还有点要注意就是在改动过的后如果要测试是否成功要重新启动次机器才可以哦我就是没有重起所以输入java -version直提示没有成功害我郁闷了老久嘿嘿:}) 0
相关文章读者评论发表评论 |
|