关闭

classLoader

1461人阅读 评论(0) 收藏 举报

众所周知,Java 2之后在ClassLoader中使用了parent-Delegation模式,目的是为了简化User-defined ClassLoader的实现和更好的安全性。
ClassLoader通常作为Java 安全性的第一道屏障,


  1. 它会阻止恶意代码对原有可信任代码的干扰。
  2. 保护可信任代码。
  3. 将不同的代码分类(称之为protection domains 或 runtime domain)。


1. ClassLoader会在运行时将每一个加载过的class分配到一个唯一命名空间([i]name-space[/i])之下。不同的class根据加载的class loader的不同,被分配到不同的name-space。JVM会为每一个class loader维护一个唯一的name-space名称。一旦一个class A 已经被加载并且被安置在name-space N下,就不可能在加载另一个A 在同一个name-space下。

2. Java语言中的包访问成员(friendly)实际上指的是运行时包访问可见,而不是编译时。因此当你试图访问不在同一个runtime package的成员是(即便在编译时它们在同一个包内,但是却由不同的class loader加载)也同样会得到java.lang.IllegalAccessException: Class A can not access a member of class B with modifiers "" 这样的异常。

 

3.一个User-defined必须依赖其他的Class loader,至少需要system class loader,来协助它完成对某些class的加载工作。在1.2之后,每一个class loader除了bootstrap class loader都有一个parent class loader。每一次需要加载class时,首先会去请求parent class loader来加载这个class,如果不成功才会自己进行加载工作。这称为parent-delegation model。
如果你违反了这一协定的话,通常你会得到一个NoClassDefFoundError因为你的class Loader无法找到一些Java API中的类 ,比如说java.lang.Object。
你可能想如果将这些Java API中的类也放在你的class loader的路径下,是否就可以了呢?JVM不会允许你这样做的。你会得到:java.lang.SecurityException: Prohibited package name: java.lang,这样的异常。在Java 1.2之后,所有的java core api都由一个JVM内置的class loader加载,并且java 安全机制不允许这些类或接口被除此之外的class loader加载。

4.在一个缺省的JVM环境下,通常存在两个Class Loader。一个就是所谓的bootstrap class loader,它用来加载所有的java core api(包括所有java包下的类),另一个是系统class loader,它用来加载你定义的class_path下的类。
通常使用Class.getClassLoader()方法可以查询到加载这个class的class loader的信息。但是对于sun 的 jvm 实现而言,对于core api的class这样做只会得到null。(见 java doc)。
Ps: 系统class loader为sun.misc.Launcher$AppClassLoader。

 

5. Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime. The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type; if the element type is a primitive type, then the array class has no class loader.

6.JVM在运行时会产生三个ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader.其中,Bootstrap是用C++编写的,我们在Java中看不到它,是null。它用来加载核心类库,在JVM源代码中这样写道:
static const char classpathFormat[] =
"%/lib/rt.jar:"
"%/lib/i18n.jar:"
"%/lib/sunrsasign.jar:"
"%/lib/jsse.jar:"
"%/lib/jce.jar:"
"%/lib/charsets.jar:"
"%/classes";

7.

  • getClassLoader() on a Class instance. ClassLoader.getSystemClassLoader(). Thread.currentThread().getContextClassLoader().
  •  
  •  
  • An application-specific method to retrieve a classloader. 
  • 0
    0

    查看评论
    * 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
      个人资料
      • 访问:106727次
      • 积分:1429
      • 等级:
      • 排名:千里之外
      • 原创:31篇
      • 转载:15篇
      • 译文:0篇
      • 评论:11条