刚开始学习J2SE的时候,大家在Windows下配置JDK环境变量时应该对classpath变量的配置有印象:
classpath=".;%Java_Home%\lib\tools.jar;%Java_Home%\lib\dt.jar"再过一段时间,你肯定听一些前辈说过,不要再配置这样的系统环境变量了。这也很有道理。%Tomcat_Home%\bin下还专门留了一个脚本(setclasspath.bat或者setclasspath.sh),在它里边设置了%Java_Home%,你再启动Tomcat时就不需要配置系统的环境变量了。现在再回过头来看这个地方,竟然发现,当时学习时就没搞明白?现在至今没弄明白在配置classpath变量时问什么要在变量值中加一个"."(当前路径)。很悲哀!!!大家请帮忙看看,然后谁再给解释一下:在Windows OS下装完jre(不配置环境变量), 请问安装完,jre安装程序将部分文件写入%windir%\system32下了,不知道有没有dll文件,然后在任何一个地方打开一个cmd,输入java 都有回显? 这又是怎么一个实现方式?有没有一些权威的资料来解释一下?顺便贴出来一些相关的信息。
1.classpath中可加载的内容包括:路径(目录名,如".")、jar包、zip包.
2.java -cp(-classpath) /<path>/xxx.jar HelloWord  其中-cp(-classpath)跟在Windows OS中配置系统环境变量本质一样
3.JVM启动时,三个classloader:bootstrap classloader-->extension classloader-->system classloader

解决方案 »

  1.   

     这个只要配下PATH就可以了吧
      为什么只装jre,而不直接装JDK呢
      

  2.   

    不需要啊,想用JDK的时候直接从别的地方Copy一个就得了,我就不装JDK.
    电脑上只用装一个jre就可以了.
      

  3.   

    本来想听听更多的人的说法那,不过找到答案了,还是比较权威的,贴出来吧。
    http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/classpath.html大家还要要补充的,请不吝赐教,晚两天再结贴吧。
      

  4.   

    朋友,刚入门的时候一定要寻根究底地学习,切莫浮躁!等你可以做东西的时候,就不再需要在系统中配置环境变量了。在系统中配置了反而会影响你使用!那我就在这里在唠叨几句吧!JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构:bootstrap classloader --> extension classloader --> system classloader
    类加载器的顺序是: 先是bootstrap classloader,然后是extension classloader,最后才是system classloader.Java源代码文件的编译和Class字节码文件的载入执行,都是使用Launcher初始化的system classloader作为类载入器的,我们无法动态的改变system classloader,更无法让JVM使用我们自己的classloader来替换system classloader,根据全盘负责原则,就限制了编译和运行时,我们无法直接显式的使用一个system classloader寻找不到的Class,即我们只能使用Java核心类库,扩展类库和CLASSPATH中的类库中的Class.
    下面我就举2个例子来说明一下这个问题:
    1.HelloWebLogic.javapublic class HelloWebLogic{
      public static void main(String tdy218[]){
       System.out.println("Hello WebLogic!");
     }
    }上面这个例子大家一定很熟悉吧!
    假如JDK安装在了D:\java\jdk1.4.2下了。
    在Windows OS中打开一个cmd,设置path.
    [code=BatchFile]
    set PATH=D:\java\jdk1.4.2\bin;%PATH%
    [/code]
    接着编译这个源文件:
    javac HelloWebLogic.java
    执行这个类:
    java HelloWebLogic
    echo:Hello WebLogic!2.HelloWebLogic.javaimport utils.netAddresses;
    public class HelloWebLogic{
      public static void main(String tdy218[]){
       netAddresses.main(tdy218);
     }
    }这里我引用了一个jar包里的一个类,这就需要你在编译、执行的时候加载这个jar包。
    同样再打开一个cmd,在其中执行:
    set PATH=D:\java\jdk1.4.2\bin;%PATH%
    编译源文件:
    javac -classpath D:\bea816\weblogic81\server\lib\weblogic.jar HelloWebLogic.java
    执行编译出来的字节码文件:
    java -classpath D:\bea816\weblogic81\server\lib\weblogic.jar HelloWebLogic这时,你就会看到一个java.lang.NoClassDefFoundError的异常(在Linux OS下编译、执行):
    HelloWebLogic Exception in thread "main" java.lang.NoClassDefFoundError: HelloWebLogic
    at gnu.java.lang.MainThread.run(libgcj.so.7rh)
    Caused by: java.lang.ClassNotFoundException: HelloWebLogic not found in gnu.gcj.runtime.SystemClassLoader{urls=[file:/opt/bea816/weblogic81/server/lib/weblogic.jar], parent=gnu.gcj.runtime.ExtensionClassLoader{urls=[], parent=null}}
       at java.net.URLClassLoader.findClass(libgcj.so.7rh)
       at gnu.gcj.runtime.SystemClassLoader.findClass(libgcj.so.7rh)
       at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
       at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
       at gnu.java.lang.MainThread.run(libgcj.so.7rh)

    看到了吧?
    在回过头去看看:
    JVM启动时(执行java命令时),会形成由三个类加载器组成的初始类加载器层次结构:bootstrap classloader --> extension classloader --> system classloader
    system classloader -系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者 CLASSPATH操作系统属性所指定的JAR类包和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()找到该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。
    Caused by: java.lang.ClassNotFoundException: HelloWebLogic not found in gnu.gcj.runtime.SystemClassLoader
    Java源代码文件的编译和Class字节码文件的载入执行,都是使用Launcher初始化的system classloader作为类载入器的,我们无法动态的改变system classloader,更无法让JVM使用我们自己的classloader来替换system classloader,根据全盘负责原则,就限制了编译和运行时,我们无法直接显式的使用一个system classloader寻找不到的Class,即我们只能使用Java核心类库,扩展类库和CLASSPATH中的类库中的Class.
    也就是是说:
    HelloWebLogic.class是我们自定一个类文件,其中调用了其他的路径下的类文件(utils.netAddresses),这就需要我们自己在运行JVM加载类文件时,加上"-cp或-classpath"参数来加载自定义的ClassLoader覆盖SystemClassLoader,而默认的class path是当前路径,也就是HelloWebLogic.class,而且默认的SystemClassLoader已经将他加载到了jvm运行时的classpath中去了,现在想使用自定义的ClassLoader,就需要将当前路径包含到自定义的ClassLoader中,这样JVM通过在"-cp或者-classpath"加载的类文件中搜索HelloWebLogic.class才能搜索到。
    所以正确的执行方式应该是这样的:
    java -classpath .;D:\bea816\weblogic81\server\lib\weblogic.jar HelloWebLogic
    不然就会抛出形如:java.lang.NoClassDefFoundError.现在大家应该明白了吧?
    下面贴出来jdk1.5 docs中的一篇名为《Setting the class path》的文章中关于配置classpath时,为什么要加"."的权威说明,我上面只是结合实际应用环境及JVM类加载机制和异常信息来更深入的说明这个问题,分析中因为个人水平原因,难免有些偏差.望 对JVM有深入研究的网友不吝赐教!接着我会顺带着将一个老生长谈的问题在唠叨一遍:"java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError”
      

  5.   

    《Setting the class path》一文中对classpath中"."配置的解释:The default class path is the current directory. Setting the CLASSPATH variable or using the -classpath command-line option overrides that default, so if you want to include the current directory in the search path, you must include "." in the new settings.
    应该是System Classloader默认的classpath是当前目录,当你加载一些需要的jar包、目录、zip包时,可以在操作系统中设置CLASSPATH变量,变量值指向你要加载的jar包、目录、zip包,也可以在执行的java命令后加上"-classpath"或者"-cp" 参数,要想让System Classloader加载你需要的类文件,你当然要将System Classloader默认的classpath,也就是当前路径包含到你当前的"-classpath"或者"-cp" 参数后面,以重写System Classloader默认的classpath.Over !
      

  6.   

    下面咱们再来看看java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError
    你Google一下,就会发现已经早有人分析过了,我这里贴出来的内容也会跟别人写的有重复的地方,因为某些资源都是一样的。ClassNotFoundException : 类未找到异常
    NoClassDefFoundError : 类未定义异常以下是Java API中关于这两个类的说明:
    java.lang.NoClassDefFoundErrorpublic class NoClassDefFoundError extends LinkageError
    当 Java 虚拟机或 ClassLoader 实例试图在类的定义中加载(作为通常方法调用的一部分或者作为使用 new 表达式创建的新实例的一部分),但无法找到该类的定义时,抛出此异常。 当前执行的类被编译[执行]时,[在当前目录下]所搜索的类定义存在,但无法在[classpath中]找到该[类的]定义。 从以下版本开始:JDK1.0 
    文本为个人感觉翻译的不好的应该删除的内容,"[ ]"中加入的文本为个人认为应当补充的内容。不当的地方望指正!java.lang.ClassNotFoundException
    public class ClassNotFoundException extends Exception
    当应用程序试图使用以下方法通过字符串名加载类时,抛出该异常: Class 类中的 forName 方法。 
    ClassLoader 类中的 findSystemClass 方法。 
    ClassLoader 类中的 loadClass 方法。 
    但是没有找到具有指定名称的类的定义。 从 1.4 版本开始,此异常已经更新,以符合通用的异常链机制。在构造时提供并通过 getException() 方法访问的“加载类时引发的可选异常”,现在被称为原因,它可以通过 Throwable.getCause() 方法以及与上面提到的“遗留方法”来访问。 从以下版本开始:JDK1.0 再回过头看看上面这个异常:java.net.URLClassLoader类在调用findClass方法在classpath中寻找HelloWebLogic类时寻找不到,先抛出ClassNotFoundException,然后这个类在JVM中运行的时候,先从main函数执行,当执行到
      

  7.   

    参考资料:
    1.《Java虚拟机类加载顺序》
    文章地址: http://blog.163.com/ainiyiwannian2046@126/blog/static/4910134020093224125108/
    2.Sun  Java 1.5 docs 《Setting the class path》
    文章地址:
    http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/classpath.html
    3.《classpath详解(谨献给那些找不到北的朋友) 》
    文章地址:
    http://www.javaresearch.org/article/58619.htm
    4.《类装入问题解密,第 2 部分: 基本的类装入异常》
    文章地址:
    http://www.ibm.com/developerworks/cn/java/j-dclp2.html
      

  8.   

    前后几个帖子发的可能有点乱,我已将此贴整理出来了,贴在我的博客里了。文章标题:《Java 环境变量的那些事儿》文章地址:http://blog.csdn.net/tdy218/archive/2009/07/08/4330762.aspx
      

  9.   

    请帮忙大家看看下面这个:在Windows OS下装完jre(不配置环境变量), 请问安装完,jre安装程序将部分文件写入%windir%\system32下了,不知道有没有dll文件,然后在任何一个地方打开一个cmd,输入java 都有回显? 这又是怎么一个实现方式?
    有没有一些权威的资料来解释一下?
      

  10.   

    windows常识啊
    在你的系统的path环境变量所指的某个目录中有java.exe存在
      

  11.   

    那些路径都是java里自带的一些class类的路径,你编写程序有时用到java自带的类就是从那里调用的,没有那些路径,你的编译器就不知道到哪找类。
    至于那个 “。”,指的是你当前的类,你有时候需要编写自己的类,这些类一般习惯直接跟代码的文本放在一起,所以,“。”的用意就是让系统先找你当前的路径,就是跟你的代码放在一起的地方,然后再去java打包类的地方找。没什么用,就是方便点,大家编写程序习惯了,很随意的喜欢把代码和自己编写的代码放在一起。就这。
    马士兵的开始几章讲过这个问题。慢慢来别急。有时间看看那视频,还不错的。希望能帮到你,我也才学,呵呵!
      

  12.   

    友情顶顶啊
    暑假 再次 自学java
    一门 人见人爱的语言
    呵呵
    楼主加油
    关注………………
      

  13.   

    我忽略了这个问题,惭愧!
    默认情况下,安装完jre,JRE的安装程序将java.exe、javaw.exe等程序拷贝到%SystemRoot%\system32下了。
    又是默认情况下,Windows操作系统装好,会自动设置系统运行时需要的环境变量(其实是写到注册表中去了)。
    当你在开始-->运行框 中输入一些系统的命令,可以看到回显,是因为相关的程序被设置到环境变量中去了,在系统环境变量中有个Path(Win OS 不区分大小写)变量,Win XP OS 32bit下默认是:%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem。JRE安装程序将一些关键的可执行文件(java.exe)放到%SystemRoot%\system32下了,这也是安装完JRE即可执行java命令(程序名)的原因。快毕业的时候,我找到过一个开源的jar包,他可以向注册表中任何地方写内容,可以将java 32 app做成随即启动的,我还写了个小程序:
    不过我也考虑过将JDK安装后的bin目录也写进注册表,同时修改JDK的安装程序,使他在安装时可以像MySQL一样,有个选项,是否将/bin写进系统的path环境变量中。安装完MySQL后的PATH变量值:%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;D:\Install\MySQL\MySQL Server 5.1\bin
    我当时以为MySQL的安装程序做的很好,很人性化,JDK也应该这样做,可等到我能做程序的时候,我就发现,SUN这样做也对...同时附上注册表中环境变量所在的位置:
    用户环境变量列表的注册表键:
    HKEY_CURRENT_USER\Environment系统环境变量列表的注册表键:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
    我现在已经快半年没怎么写过代码了...谁需要《Java利用第三方包操作Win OS 注册表》的资料.留个E-Mail即可,我看人不多的话我给发一下.
      

  14.   

    頂下吧,不過我之前就沒配過path!
      

  15.   

    其实一个不配也是行的,
    不过我们平常为了方便都设了环境变量,
    而且一般是配两个(PATH、JAVA_HOME)
    CLASSPATH可以不用配
      

  16.   

    http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/classpath.html