深入探讨Java类加载器 - 编程入门网
器指定的由所有 Web 应用共享的目录下面。
当出现找不到类的错误时,检查当前类的类加载器和当前线程的上下文 类加载器是否正确。 在介绍完类加载器与 Web 容器的关系之后,下面介 绍它与 OSGi 的关系。 类加载器与 OSGi OSGi™ 是 Java 上的动态模块系统。它为开发人员提供了面向服务和基于组件的运行环境,并提 供标准的方式用来管理软件的生命周期。OSGi 已经被实现和部署在很多产品上 ,在开源社区也得到了广泛的支持。Eclipse 就是基于 OSGi 技术来构建的。 OSGi 中的每个模块(bundle)都包含 Java 包和类。模块可以声明它所依赖 的需要导入(import)的其它模块的 Java 包和类(通过 Import-Package), 也可以声明导出(export)自己的包和类,供其它模块使用(通过 Export- Package)。也就是说需要能够隐藏和共享一个模块中的某些 Java 包和类。这 是通过 OSGi 特有的类加载器机制来实现的。OSGi 中的每个模块都有对应的一 个类加载器。它负责加载模块自己包含的 Java 包和类。当它需要加载 Java 核 心库的类时(以 java 开头的包和类),它会代理给父类加载器(通常是启动类 加载器)来完成。当它需要加载所导入的 Java 类时,它会代理给导出此 Java 类的模块来完成加载。模块也可以显式的声明某些 Java 包和类,必须由父类加 载器来加载。只需要设置系统属性 org.osgi.framework.bootdelegation 的值 即可。 假设有两个模块 bundleA 和 bundleB,它们都有自己对应的类加 载器 classLoaderA 和 classLoaderB。在 bundleA 中包含类 com.bundleA.Sample,并且该类被声明为导出的,也就是说可以被其它模块所使 用的。bundleB 声明了导入 bundleA 提供的类 com.bundleA.Sample,并包含一 个类 com.bundleB.NewSample 继承自 com.bundleA.Sample。在 bundleB 启动 的时候,其类加载器 classLoaderB 需要加载类 com.bundleB.NewSample,进而 需要加载类 com.bundleA.Sample。由于 bundleB 声明了类 com.bundleA.Sample 是导入的,classLoaderB 把加载类 com.bundleA.Sample 的工作代理给导出该类的 bundleA 的类加载器 classLoaderA。classLoaderA 在其模块内部查找类 com.bundleA.Sample 并定义它,所得到的类 com.bundleA.Sample 实例就可以被所有声明导入了此类的模块使用。对于以 java 开头的类,都是由父类加载器来加载的。如果声明了系统属性 org.osgi.framework.bootdelegation=com.example.core.*,那么对于包 com.example.core 中的类,都是由父类加载器来完成的。 OSGi 模块的 这种类加载器结构,使得一个类的不同版本可以共存在 Java 虚拟机中,带来了 很大的灵活性。不过它的这种不同,也会给开发人员带来一些麻烦,尤其当模块 需要使用第三方提供的库的时候。下面提供几条比较好的建议: 如果一 个类库只有一个模块使用,把该类库的 jar 包放在模块中,在 Bundle- ClassPath 中指明即可。 如果一个类库被多个模块共用,可以为这个类 库单独的创建一个模块,把其它模块需要用到的 Java 包声明为导出的。其它模 块声明导入这些类。 如果类库提供了 SPI 接口,并且利用线程上下文类 加载器来加载 SPI 实现的 Java 类,有可能会找不到 Java 类。如果出现了 NoClassDefFoundError 异常,首先检查当前线程的上下文类加载器是否正确。 通过 Thread.currentThread().getContextClassLoader() 就可以得到该类加载 器。该类加载器应该是该模块对应的类加载器。如果不是的话,可以首先通过 class.getClassLoader() 来得到模块对应的类加载器,再通过 Thread.currentThread().setContextClassLoader() 来设置当前线程的上下文 类加载器。 总结 类加载器是 Java 语言的一个创新。它使得动态 安装和更新软件组件成为可 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |