转:关于JAVA项目中CLASSPATH路径详解
在dos下编译Java程序,就要用到classpath这个概念,尤其是在没有设置环境变量的时候。classpath就是存放.class等编译后文件的路径。
javac:如果当前你要编译的Java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加上-classpath参数,通过使用以下三种类型的方法 来指导编译器在编译的时候去指定的路径下查找引用类。
(1).绝对路径:javac -classpath c:/junit3.8.1/junit.jar Xxx.java
(2).相对路径:javac -classpath ../junit3.8.1/Junit.javr Xxx.java
(3).系统变量:javac -classpath %CLASSPATH% Xxx.java (注意:%CLASSPATH%表示使用系统变量CLASSPATH的值进行查找,这里假设Junit.jar的路径就包含在CLASSPATH系统变量中)
javac 绝对路径的使用:
javac:假设你要编译的类文件名叫:HelloWorld.java,其完全路径为:D:/java/HelloWorld.java。但你所在的当前目录是:C:/Documents and Settings/peng>。如果想在这里执行编译,会有什么结果呢?
(1).C:/Documents and Settings/peng> javac HelloWorld.java 这时编译器会给出如下的错误提示信息:
error: cannot read: HelloWorld.java
这是因为默认情况下javac是在当前目录下查找类文件,很明显这个路径不是我们存放类文件的地方,所以就会报错了
(2).C:/Documents and Settings/peng>javac D:/java/HelloWorld.java
这时编译成功。
所以,只要你执行javac命令的目录不是类文件存放的目录,你就必须在javac命令中显式地指定类文件的路径。
java -classpath的使用:
java:假设我们的CLASSPATH设置为:D:/peng/java/pro ,在该目录下有三个文件:HelloWorld.java / HelloWorldExtendsTestCase / HelloWorldExtendsHelloWorld。这三个文件的类声明分别如下:
HelloWorld.java :public class HelloWorld
HelloWorldExtendsHelloWorld.java :public class HelloWorldExtendsHelloWorld extends HelloWorld
HelloWorldExtendsTestCase.java:public class HelloWorldExtendsTestCase extends junit.framework.TestCase
假设我们已经按照上面关于javac -classpath和javac 绝对路径的使用,顺利地完成了三个文件地编译。现在我们在C:/Documents and Settings/peng>目录下执行这三个.class文件
(1).C:/Documents and Settings/peng>java HelloWorld
Hello World
可以看到执行成功。为什么我们在 C:/Documents and Settings/peng>执行命令,JVM能够找到D:/peng/java/pro/HelloWorld.class文件呢?这是因为我们配置了系统变量CLASSPATH,并且指向了目录:D:/peng/java/pro 。所以JVM会默认去该目录下加载类文件,而不需要指定.class文件的绝对路径了。
(2).C:/Documents and Settings/peng>JavaHelloWorldExtendsHelloWorld
Hello World
可以看到执行成功了。HelloWorldExtendsHelloWorld继承了HelloWorld类,所以在执行时JVM会先查找在CLASSPATH下是否存在一个HelloWorld.class文件,因为我们已经成功编译了HelloWorld 类了,所以可以成功执行HelloWorldExtendsHelloWorld.class
(3).C:/Documents and Settings/peng>JavaHelloWorldExtendsTestCase
Exception in thread "main" java.lang.NoClassDefFoundError: junit/framework/TestCase
可以看到程序抛出异常了,提示找不到junit.framework.TestCase文件。为什么同样在:/peng/java/pro 下,HelloWorldExtendsHelloWorld.class就可以成功执行,而这个就不行了呢?这是因为: junit.framework.TestCase.class文件并不存在于当前目录下,所以为了能够让程序成功运行,我们必须通过指定CLASSPATH的方式,让JVM可以找到junit.framework.TestCase这个类,如(4):
(4). C:/Documents and Settings/peng>java -classpath %CLASSPATH% HelloWorldExtendsTestCase
Hello World
总结:
(1).何时需要使用-classpath:当你要编译或执行的类引用了其它的类,但被引用类的.class文件不在当前目录下时,就需要通过-classpath来引入类
(2).何时需要指定路径:当你要编译的类所在的目录和你执行javac命令的目录不是同一个目录时,就需要指定源文件的路径(CLASSPATH是用来指定.class路径的,不是用来指定.java文件的路径的)
JAVA获取classpath路径:
public URL getResource (String name);
public InputStream getResourceAsStream (String name);
这里name是资源的类路径,它是相对与“/”根路径下的位置。getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
但是真正使用的不是ClassLoader的这两个方法,而是Class的 getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或 YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,不过根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader来做的,所以只需要使用 Class对象的这两个方法就可以了。
因此,直接调用 this.getClass().getResourceAsStream(String name) ;获取流,静态化方法中则使用ClassLoader.getSystemResourceAsStream (String name) ; 。
下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。
1.this.getClass().getResource("")
得到的是当前类class文件的URI目录。不包括自己!
如:file:/D:/workspace/jbpmtest3/bin/com/test/
2.this.getClass().getResource("/")
得到的是当前的classpath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
3.this.getClass() .getClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
4.ClassLoader.getSystemResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
5.Thread.currentThread().getContextClassLoader ().getResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
6.ServletActionContext.getServletContext().getRealPath(“/”)
Web应用程序 中,得到Web应用程序的根目录的绝对路径。这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。
如:file:/D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/WebProject
注意点:
1.尽量不要使用相对于System.getProperty("user.dir")当前用户目录的相对路径。这是一颗定时炸 弹,随时可能要你的命。
2.尽量使用URI形式的绝对路径资源。它可以很容易的转变为URI,URL,File对象。
3.尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面ClassLoaderUtil类的public static URL getExtendResource(String relativePath)方法已经能够使用相对于classpath的相对路径定位所有位置的资源。
4.绝对不要使用硬编码的绝对路径。因为,我们完全可以使用ClassLoader类的getResource("")方法得到当前classpath的绝对路径。如果你一定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!
获得CLASSPATH之外路径的方法:
URL base = this.getClass().getResource(""); //先获得本类的所在位置,如/home/popeye/testjava/build/classes/net/
String path = new File(base.getFile(), "……/……/……/"+name).getCanonicalPath(); //就可以得到/home/popeye/testjava/name
另外,如果从ANT启动程序,this.getClass().getResource("")取出来的比较怪,直接用JAVA命令行调试就可成功。
在dos下编译Java程序,就要用到classpath这个概念,尤其是在没有设置环境变量的时候。classpath就是存放.class等编译后文件的路径。
javac:如果当前你要编译的java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加上-classpath参数,通过使用以下三种类型的方法 来指导编译器在编译的时候去指定的路径下查找引用类。
(1).绝对路径:javac -classpath c:/junit3.8.1/junit.jar Xxx.java
(2).相对路径:javac -classpath ../junit3.8.1/Junit.javr Xxx.java
(3).系统变量:javac -classpath %CLASSPATH% Xxx.java (注意:%CLASSPATH%表示使用系统变量CLASSPATH的值进行查找,这里假设Junit.jar的路径就包含在CLASSPATH系统变量中)
javac 绝对路径的使用:
javac:假设你要编译的类文件名叫:HelloWorld.java,其完全路径为:D:/java/HelloWorld.java。但你所在的当前目录是:C:/Documents and Settings/peng>。如果想在这里执行编译,会有什么结果呢?
(1).C:/Documents and Settings/peng> javac HelloWorld.java 这时编译器会给出如下的错误提示信息:
error: cannot read: HelloWorld.java
这是因为默认情况下javac是在当前目录下查找类文件,很明显这个路径不是我们存放类文件的地方,所以就会报错了
(2).C:/Documents and Settings/peng>javac D:/java/HelloWorld.java
这时编译成功。
所以,只要你执行javac命令的目录不是类文件存放的目录,你就必须在javac命令中显式地指定类文件的路径。
java -classpath的使用:
java:假设我们的CLASSPATH设置为:D:/peng/java/pro ,在该目录下有三个文件:HelloWorld.java / HelloWorldExtendsTestCase / HelloWorldExtendsHelloWorld。这三个文件的类声明分别如下:
HelloWorld.java :public class HelloWorld
HelloWorldExtendsHelloWorld.java :public class HelloWorldExtendsHelloWorld extends HelloWorld
HelloWorldExtendsTestCase.java:public class HelloWorldExtendsTestCase extends junit.framework.TestCase
假设我们已经按照上面关于javac -classpath和javac 绝对路径的使用,顺利地完成了三个文件地编译。现在我们在C:/Documents and Settings/peng>目录下执行这三个.class文件
(1).C:/Documents and Settings/peng>java HelloWorld
Hello World
可以看到执行成功。为什么我们在 C:/Documents and Settings/peng>执行命令,JVM能够找到D:/peng/java/pro/HelloWorld.class文件呢?这是因为我们配置了系统变量CLASSPATH,并且指向了目录:D:/peng/java/pro 。所以JVM会默认去该目录下加载类文件,而不需要指定.class文件的绝对路径了。
(2).C:/Documents and Settings/peng>JavaHelloWorldExtendsHelloWorld
Hello World
可以看到执行成功了。HelloWorldExtendsHelloWorld继承了HelloWorld类,所以在执行时JVM会先查找在CLASSPATH下是否存在一个HelloWorld.class文件,因为我们已经成功编译了HelloWorld 类了,所以可以成功执行HelloWorldExtendsHelloWorld.class
(3).C:/Documents and Settings/peng>javaHelloWorldExtendsTestCase
Exception in thread "main" java.lang.NoClassDefFoundError: junit/framework/TestCase
可以看到程序抛出异常了,提示找不到junit.framework.TestCase文件。为什么同样在:/peng/java/pro 下,HelloWorldExtendsHelloWorld.class就可以成功执行,而这个就不行了呢?这是因为: junit.framework.TestCase.class文件并不存在于当前目录下,所以为了能够让程序成功运行,我们必须通过指定CLASSPATH的方式,让JVM可以找到junit.framework.TestCase这个类,如(4):
(4). C:/Documents and Settings/peng>java -classpath %CLASSPATH% HelloWorldExtendsTestCase
Hello World
总结:
(1).何时需要使用-classpath:当你要编译或执行的类引用了其它的类,但被引用类的.class文件不在当前目录下时,就需要通过-classpath来引入类
(2).何时需要指定路径:当你要编译的类所在的目录和你执行javac命令的目录不是同一个目录时,就需要指定源文件的路径(CLASSPATH是用来指定.class路径的,不是用来指定.java文件的路径的)
JAVA获取classpath路径:
public URL getResource (String name);
public InputStream getResourceAsStream (String name);
这里name是资源的类路径,它是相对与“/”根路径下的位置。getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
但是真正使用的不是ClassLoader的这两个方法,而是Class的 getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或 YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,不过根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader来做的,所以只需要使用 Class对象的这两个方法就可以了。
因此,直接调用 this.getClass().getResourceAsStream(String name) ;获取流,静态化方法中则使用ClassLoader.getSystemResourceAsStream (String name) ; 。
下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。
1.this.getClass().getResource("")
得到的是当前类class文件的URI目录。不包括自己!
如:file:/D:/workspace/jbpmtest3/bin/com/test/
2.this.getClass().getResource("/")
得到的是当前的classpath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
3.this.getClass() .getClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
4.ClassLoader.getSystemResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
5.Thread.currentThread().getContextClassLoader ().getResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
6.ServletActionContext.getServletContext().getRealPath(“/”)
Web应用程序 中,得到Web应用程序的根目录的绝对路径。这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。
如:file:/D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/WebProject
注意点:
1.尽量不要使用相对于System.getProperty("user.dir")当前用户目录的相对路径。这是一颗定时炸 弹,随时可能要你的命。
2.尽量使用URI形式的绝对路径资源。它可以很容易的转变为URI,URL,File对象。
3.尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面ClassLoaderUtil类的public static URL getExtendResource(String relativePath)方法已经能够使用相对于classpath的相对路径定位所有位置的资源。
4.绝对不要使用硬编码的绝对路径。因为,我们完全可以使用ClassLoader类的getResource("")方法得到当前classpath的绝对路径。如果你一定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!
获得CLASSPATH之外路径的方法:
URL base = this.getClass().getResource(""); //先获得本类的所在位置,如/home/popeye/testjava/build/classes/net/
String path = new File(base.getFile(), "……/……/……/"+name).getCanonicalPath(); //就可以得到/home/popeye/testjava/name
另外,如果从ANT启动程序,this.getClass().getResource("")取出来的比较怪,直接用JAVA命令行调试就可成功。
转:关于JAVA项目中CLASSPATH路径详解的更多相关文章
- 《Java项目中classpath路径详解》
项目里用到了classpath路径来引用文件,那么classpath指的是哪里呢 我首先把上面的applicationContext.xml文件放在了src目录下发现可以. 那么classpath到底 ...
- 关于JAVA项目中CLASSPATH路径详解
写的不错:http://blog.csdn.net/cheney521/article/details/8672066 以下内容源于复制,把自己觉得不错的东西收集起来: 在dos下编译java程序,就 ...
- java web中 classpath路径 详解
在使用ssh等框架开发web程序时配置文件(xml和properties)存放的路径一般为src下,当部署程序时则必须存在于classes路径下,具体如下 src不是classpath, WEB-IN ...
- (转) eclipse项目中.classpath文件详解
背景:对于java项目中.classpath文件中的相关定义一直不是很了解,有必要进行深入的学习. 1 前言 在使用eclipse或者myeclipse进行Java项目开发的时候,每个project( ...
- Java项目中classpath路径
1.src不是classpath, WEB-INF/classes.lib.resources才是classpath,WEB-INF/是资源目录, 客户端不能直接访问. 2.WEB-INF/class ...
- java项目中classpath路径到底指的是哪里?
本文转自:http://blog.csdn.net/javaloveiphone/article/details/51994268 1.src不是classpath, WEB-INF/classes和 ...
- eclipse项目中.classpath文件详解
1 前言 在使用eclipse或者myeclipse进行java项目开发的时候,每个project(工程)下面都会有一个.classpath文件,那么这个文件究竟有什么作用? 2 作用 .classp ...
- java项目中.classpath,.settings,.project,mymetadata文件的作用
今天犯了一个错误,误修改了本地的.classpath文件,导致项目好多地方报错,之前也没有仔细的研究过项目中的一些生成文件的作用. 今天特此进行记录. 不管我们在eclipse中新建任何的Java项目 ...
- java项目中的路径获取,request
java web项目中获取项目根路径(tomcat可运行的web源码的路径)的方式: 分为两种情况: 情况一: 在eclipse.inde等开发工具中获取(注:如下代码所在的类必须是控制层所在包下的类 ...
随机推荐
- 爬虫学习--Day3(小猿圈爬虫开发_1)
爬虫基础简介 前戏: 1.你是否在夜深人静的时候,想看一些让你更睡不着的图片 2.你是否在考试或者面试前夕,想看一些具有针对性的题目和面试题 3.你是否想在杂乱的网络世界中获取你想要的数据 什么是爬虫 ...
- 『题解』洛谷P4016 负载平衡问题
title: categories: tags: - mathjax: true --- Problem Portal Portal1:Luogu Portal2: LibreOJ Descripti ...
- PHP yaf显示错误提示
PHP yaf显示错误提示 1就是配置文件的那个错误 <pre>error_reporting(E_ALL);</pre> 2init.php文件的<pre>fun ...
- centos6的mysql安装
1.安装mysql服务端 yum install mysql-server yum install mysql-devel 2.下载mysql的压缩包 wget http://dev.m ...
- 构建大型 Vue.js 项目的10条建议
下面是我在开发大型 Vue 项目时的最佳实践.这些技巧将帮助你开发更高效.更易于维护和共享的代码. 今年做自由职业的时候,我有机会开发了一些大型 Vue 应用程序.我所说的这些项目,Vuex stor ...
- 网络编程--UDP通讯
UTP传输 public class Send1 { public static void main(String[] args) throws Exception { Scanner sc=new ...
- cocos creator 3D | 蚂蚁庄园运动会星星球
上一篇文章写了一个简易版的蚂蚁庄园登山赛,有小伙伴留言说想要看星星球的,那么就写起来吧! 效果预览 配置环境 cocos creator 3d 1.0.0 小球点击 3d里节点无法用 cc.Node. ...
- 用PHP+Redis实现延迟任务,实现自动取消订单
简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本 ...
- ArcGIS API For Javascript :如何制作地图切换器
大部分情况下我们开发会使用原生的地图切换器,由于每个项目的页面风格不同,业务场景不同,因此需要做一些样式不同的地图切换器. 首先可以照猫画虎,自己照着地图切换器的样式抄一个,或者看看主流的地图切换器都 ...
- MySQL基础知识面试与答案
1.Mysql 的存储引擎,myisam和innodb的区别. 答: 1.MyISAM 是非事务的存储引擎,适合用于频繁查询的应用.表锁,不会出现死锁,适合小数据,小并发. 2.innodb是支持事务 ...