WEB开发网
开发学院WEB开发Jsp 类装入问题解密,第 3 部分: 处理更少见的类装入问... 阅读

类装入问题解密,第 3 部分: 处理更少见的类装入问题

 2008-01-05 08:49:38 来源:WEB开发网   
核心提示:这个四部分构成的文章系列研究 java™ 的类装入问题,帮助应用程序开发人员理解和调试可能碰到的问题,类装入问题解密,第 3 部分: 处理更少见的类装入问题,在第 3 部分中,来自 IBM Hursley 实验室的作者 Lakshmi Shankar 和 Simon Burns 在本系列前两部分的基础之上,
这个四部分构成的文章系列研究 java™ 的类装入问题,帮助应用程序开发人员理解和调试可能碰到的问题。在第 3 部分中,来自 IBM Hursley 实验室的作者 Lakshmi Shankar 和 Simon Burns 在本系列前两部分的基础之上,具体介绍了不同种类的类装入问题,包括与类路径、类可视性和垃圾收集有关的问题。

本文是本系列中四篇文章的第三篇,它研究了在 Java 开发过程中的一些更复杂、更少见的类装入问题。造成这些问题的原因通常无法直接从症状得出;所以,解决起来既困难又费时。与本系列以前的文章一样,我们仍然提供示例来演示问题,然后讨论各种解决技术。

在开始这篇文章之前,应当熟悉类装入委托模型,以及类链接的阶段和过程。我们强烈建议您从阅读本系列的 第一篇文章 开始。

与类路径有关的问题

有一个非常简单的问题通常与用户设置的类路径有关。清单 1 和清单 2 中的示例演示了这个问题。

测试用例创建了两个类装入器,每个类装入器使用的类路径看起来相同。但是,有一个微小但是却重大的区别:一个类路径末尾有 /,而另一个没有。在这两个类路径中的一个名为 cp 的子目录中有一个类 Z(在清单 2 中)。两个类装入器都试图装入 Z


清单 1. ClasspathTest.java

import java.net.URL;
import java.net.URLClassLoader;

public class ClasspathTest {
	
    String userDir;
    URL withSlash;
    URL withoutSlash;

    ClasspathTest() {
        try {
            userDir = System.getPRoperty("user.dir");
            withSlash = new URL("file://C:/CL_Article/ClasspathIssues/cp/");
            withoutSlash = new URL("file://C:/CL_Article/ClasspathIssues/cp");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void run() {
        try {
            System.out.println(withSlash);
            URLClassLoader cl1 = new URLClassLoader(new URL[] { withSlash });
            Class c1 = cl1.loadClass("Z");
            System.out.println("Class Z loaded.");
            System.out.println(withoutSlash);
            URLClassLoader cl2 = new URLClassLoader(new URL[] { withoutSlash });
            Class c2 = cl2.loadClass("Z");
            System.out.println("Class Z loaded.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new ClasspathTest().run();
    }
}


清单 2. Z.java

public class Z {

}

这个测试用例产生以下输出:


file://C:/CL_Article/ClasspathIssues/cp/
Class Z loaded.
file://C:/CL_Article/ClasspathIssues/cp
java.lang.ClassNotFoundException: Z
    at java.net.URLClassLoader.findClass(URLClassLoader.java:376)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:572)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
    at ClasspathTest.run(ClasspathTest.java:28)
    at ClasspathTest.main(ClasspathTest.java:36)

可以看到,传递给每个 URLClassloader 的参数略有不同。提供给第一个类装入器 cl1 的类路径末尾有 /。提供给第二个类装入器 cl2 的类路径末尾没有 /。这个区别是显著的,因为类装入器假设不以 / 结尾的路径指向的是 JAR 文件。只有以 / 结尾的路径才被假定为指向目录。

因为 cl1 的类路径被当作目录,所以这个类装入器能够找到在这个位置的类 Z,并能够装入它。cl2 的类路径被假定为 JAR 文件;这个类装入器不能发现类 Z ,因为没有这个文件。所以,cl2.loadClass() 抛出 ClassNotFoundException


Tags:装入 问题 解密

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接