java classpath与ClassLoader

来源:互联网 发布:wifi显示不安全的网络 编辑:程序博客网 时间:2024/06/08 17:05

刚接触到jdbc时出现找不到数据库驱动,先抛出我的代码

public class Jdbc{public static void main(String args[]){try{Class.forName("com.mysql.jdbc.Driver");}catch(ClassNotFoundException e){e.printStackTrace();}   }}

运行开始出现找不到



经过不断找资料查信息,不断的import,classpath 设置。发现以下两种办法可以解决:

1、classpath添加  “jdk\lib\mysql-connector-java-5.0.8-bin.jar“  注意:前提是mysql的jar包已经复制到 jdk\lib\下;

2、将 mysql的jar包复制到 \jdk\jre\lib\ext 目录中

以上两种办法都可以解决问题,但是就是想不通原因。问题主要有是:

!!当mysql jar包文件复制到 jdk\lib目录下,且环境变量已经设置 'jdk\lib\" 目录,为什么当我把mysql jar包复制到 jdk\lib\ 和jdk\jre\lib\ 目录下,运行报错?找不到该类? 为什么一定要设置为jdk\lib\mysql-connector-java-5.0.8-bin.jar??


经过各种查资料,弄清楚了jvm加载class的大致原理,

---jvm默认只加载 jre\lib下如rt.jar、classes,然后加载jre\ext下的全部jar,最后加载classpath目录的class

---所以我开始配置的'jdk\lib\"或者'jdk\jre\lib\"只是具体到该目录,但其子目录默认是不加载的。需要添加环境变量为:jdk\lib\mysql-connector-java-5.0.8-bin.jar

---当然直接将jar包复制到 jre\ext\目录下,肯定是可以的



转载网络文章的 http://www.codeceo.com/article/java-classloader.html 的一段话:

当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个入口函数来调用系统的相关功能,而这些功能都被封装在不同的class文件当中,所以经常要从这个class文件中要调用另外一个class文件中的方法,如果另外一个文件不存在的,则会引发系统异常。

Java默认提供的三个ClassLoader

  1. Bootstrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件:
    URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();  for (int i = 0; i < urls.length; i++) {      System.out.println(urls[i].toExternalForm());  }

    以下内容是上述程序从本机JDK环境所获得的结果:

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/resources.jar

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/rt.jar

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/sunrsasign.jar

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/jsse.jar

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/jce.jar

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/charsets.jar

    file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/classes/

    其实上述结果也是通过查找sun.boot.class.path这个系统属性所得知的。

    System.out.println(System.getProperty("sun.boot.class.path"));

    打印结果:C:\Program Files\Java\jdk1.6.0_22\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\rt.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_22\jre\classes

  2. Extension ClassLoader:称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。
  3. App ClassLoader:称为系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。
ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。

0 0
原创粉丝点击