`

ClassLoader、ContextClassLoader加载问题(转)

    博客分类:
  • java
阅读更多
本文的目的重温ClassLoader、ContextClassLoader加载使用,展示可能忽略的东西,虽然内容不是多么复杂,但是出现一些问题而不明白原因时,会让人"抓狂"。
Java代码  
  1. public class ConfigurationPathTest {   
  2.        public static void main(String[] arr){   
  3.            ClassLoader cload = Thread.currentThread().getContextClassLoader();       
  4.            System.out.println("------------------getContextClassLoader加载指定的common/conf/configuration.xml配置文件---------------------"+cload.getResource("common/conf/configuration.xml"));   
  5.            //StandaloneContainer exo.kernel.container-2.1.2.jar   
  6.            System.out.println("---------------------getClassLoader加载指定的common/conf/configuration.xml配置文件--------------------------------:"+ConfigurationPathTest.class.getClassLoader().getResource("common/conf/configuration.xml"));   
  7.            //jar:file:/D:/workspace/ExoDemo/lib/exo.kernel.container-2.1.2.jar!/conf/configuration.xml   
  8.            //-----------------------具体类路径和classpath路径--------------------------//              
  9.            System.out.println("-------------getClassLoader加载classpath----------------"+ConfigurationPathTest.class.getResource(""));            
  10.            System.out.println("-------------getContextClassLoader加载classpath----------------"+cload.getResource(""));              
  11.            System.out.println("-------------System classpath----------------"+ConfigurationPathTest.class.getClassLoader().getResource(""));   
  12.               
  13.            //-----------------------优先从classpath加载,然后从lib的jar包加载--------------------------//   
  14.            System.out.println("-------------第二次 getClassLoader加载classpath----------------"+ConfigurationPathTest.class.getResource("/login.conf"));            
  15.            System.out.println("-------------第二次getContextClassLoader加载classpath ----------------"+cload.getResource("login.conf"));              
  16.            System.out.println("-------------第二次System classpath ----------------"+ConfigurationPathTest.class.getClassLoader().getResource("login.conf"));   
  17.               
  18.            System.out.println("-------------第3次getClassLoader加载classpath----------------"+ConfigurationPathTest.class.getResource("/login_prev.conf"));            
  19.            System.out.println("-------------第3次getContextClassLoader加载classpath----------------"+cload.getResource("login_prev.conf"));              
  20.            System.out.println("-------------第3次System classpath----------------"+ConfigurationPathTest.class.getClassLoader().getResource("login_prev.conf"));   
  21.           
  22.        }   
  23.        
  24. }  
public class ConfigurationPathTest {
       public static void main(String[] arr){
           ClassLoader cload = Thread.currentThread().getContextClassLoader();    
           System.out.println("------------------getContextClassLoader加载指定的common/conf/configuration.xml配置文件---------------------"+cload.getResource("common/conf/configuration.xml"));
           //StandaloneContainer exo.kernel.container-2.1.2.jar
           System.out.println("---------------------getClassLoader加载指定的common/conf/configuration.xml配置文件--------------------------------:"+ConfigurationPathTest.class.getClassLoader().getResource("common/conf/configuration.xml"));
           //jar:file:/D:/workspace/ExoDemo/lib/exo.kernel.container-2.1.2.jar!/conf/configuration.xml
           //-----------------------具体类路径和classpath路径--------------------------//           
           System.out.println("-------------getClassLoader加载classpath----------------"+ConfigurationPathTest.class.getResource(""));         
           System.out.println("-------------getContextClassLoader加载classpath----------------"+cload.getResource(""));           
           System.out.println("-------------System classpath----------------"+ConfigurationPathTest.class.getClassLoader().getResource(""));
           
           //-----------------------优先从classpath加载,然后从lib的jar包加载--------------------------//
           System.out.println("-------------第二次 getClassLoader加载classpath----------------"+ConfigurationPathTest.class.getResource("/login.conf"));         
           System.out.println("-------------第二次getContextClassLoader加载classpath ----------------"+cload.getResource("login.conf"));           
           System.out.println("-------------第二次System classpath ----------------"+ConfigurationPathTest.class.getClassLoader().getResource("login.conf"));
           
           System.out.println("-------------第3次getClassLoader加载classpath----------------"+ConfigurationPathTest.class.getResource("/login_prev.conf"));         
           System.out.println("-------------第3次getContextClassLoader加载classpath----------------"+cload.getResource("login_prev.conf"));           
           System.out.println("-------------第3次System classpath----------------"+ConfigurationPathTest.class.getClassLoader().getResource("login_prev.conf"));
       
       }
    
}

执行,打印内容关键罗列如下:
Java代码 复制代码 收藏代码
  1. file:/D:/workspace/UCMTest/bin/com/huaweisymantec/ucm/jcr/api/   
  2. file:/D:/workspace/UCMTest/bin/   
  3. file:/D:/workspace/UCMTest/bin/   
  4.   
  5. file:/D:/workspace/UCMTest/bin/login.conf   
  6. file:/D:/workspace/UCMTest/bin/login.conf   
  7. file:/D:/workspace/UCMTest/bin/login.conf   
  8.   
  9. jar:file:/D:/workspace/UCMTest/lib/com.huaweisymantec.ucm-1.0.jar!/login_prev.conf   
  10. jar:file:/D:/workspace/UCMTest/lib/com.huaweisymantec.ucm-1.0.jar!/login_prev.conf   
  11. jar:file:/D:/workspace/UCMTest/lib/com.huaweisymantec.ucm-1.0.jar!/login_prev.conf  
file:/D:/workspace/UCMTest/bin/com/huaweisymantec/ucm/jcr/api/
file:/D:/workspace/UCMTest/bin/
file:/D:/workspace/UCMTest/bin/

file:/D:/workspace/UCMTest/bin/login.conf
file:/D:/workspace/UCMTest/bin/login.conf
file:/D:/workspace/UCMTest/bin/login.conf

jar:file:/D:/workspace/UCMTest/lib/com.huaweisymantec.ucm-1.0.jar!/login_prev.conf
jar:file:/D:/workspace/UCMTest/lib/com.huaweisymantec.ucm-1.0.jar!/login_prev.conf
jar:file:/D:/workspace/UCMTest/lib/com.huaweisymantec.ucm-1.0.jar!/login_prev.conf

从加载路径可以看出
(1)ConfigurationPathTest.class.getResource("")是指明了具体包路径
而ClassLoader.getResource("")指明了classpath路径
(2)同样是从classpath加载,写法有一点点区别(要小心)
ConfigurationPathTest.class.getResource("/login.conf")       
ClassLoader.getResource("login.conf")
(3)getResource()方法会首先从classpath路径去找要加载的文件;如果不存在,再去jar包加载;如果都没有,返回null
(4)getResources()方法同时加载classpath和jar内的内容,如:ClassLoader.getResources("common/conf/configuration.xml");
(如果class和jar中都有此配置文件,使用不当会造成困惑:两个都加载了,到底哪个是在使用的;如果出错,哪个导致了出错)
分享到:
评论

相关推荐

    ClassLoader类加载机制和原理详解

    双亲委派模型使得系统类(如java.*开头的类)由Bootstrap ClassLoader加载,而用户自定义类由应用程序类加载器(AppClassLoader)加载。这避免了类的冲突,保持了系统类库的稳定性。但有时我们可能需要打破这种模型...

    classloader

    在Android系统中,类加载器(ClassLoader)是一个至关重要的组件,它负责查找并加载应用程序中的类。类加载器的工作机制是Java虚拟机(JVM)的一部分,但在Android中,由于其特殊的运行环境,类加载器的功能和使用...

    浅析ClassLoader

    三、上下文类加载器(ContextClassLoader) 1. 定义:在多线程环境中,每个线程都有一个与之关联的ClassLoader,称为上下文类加载器。通常,线程的上下文类加载器由创建该线程的代码设置,用于加载线程中使用的特定...

    classloader-playground, 一个简单的java依赖隔离容器类.zip

    此外,"classloader-playground"还可能包含对线程上下文类加载器(Thread Context ClassLoader)的理解和使用。线程上下文类加载器主要用于解决应用程序类加载问题,尤其是在服务提供者接口(SPI)中,允许用户...

    Tomcat研究之ClassLoader.pdf

    ### Tomcat中的ClassLoader详解 #### 一、引言 在深入了解Tomcat的工作原理时,一个重要的组成部分就是其...理解这些概念有助于开发者更好地管理部署在Tomcat上的Web应用程序,并解决可能出现的类加载冲突等问题。

    jboss 5 原理 2 classloader

    此外,Microcontainer的类加载层也支持OSGi的类加载概念,如束(Bundle)和上下文(Context),这为构建模块化和可插拔的应用程序提供了基础。尽管JBoss 5的类加载层并不完全遵循OSGi规范,但它吸取了OSGi的优点,...

    Java类加载原理解析

    除了这三种预定义的类加载器,Java还提供了一种特殊的**线程上下文类加载器(Thread Context ClassLoader)**,它允许在特定线程中加载类时使用非默认的类加载器。这在插件框架和OSGi等动态部署环境中尤其有用。 ...

    tomcat类加载器

    类加载器遵循双亲委派模型,这意味着当一个类加载器尝试加载类时,它首先会将请求委托给其父类加载器,直到到达顶层的Bootstrap ClassLoader,如果父类加载器无法找到该类,子类加载器才会尝试自己加载。 在Tomcat...

    android 动态加载class

    在整个过程中,我们需要注意权限问题,特别是从Android 6.0(API级别23)开始,动态加载可能需要请求 `READ_EXTERNAL_STORAGE` 和 `WRITE_EXTERNAL_STORAGE` 权限。 此外,Android的类加载机制遵循双亲委派模型,...

    安卓原生热更新 classloader

    当应用启动时,Android系统会使用`ClassLoader`来加载这些`.dex`文件并执行其中的代码。 `ClassLoader`是Java和安卓系统中的一个重要组件,它的主要职责是加载类到Java虚拟机(JVM)或者 Dalvik 虚拟机(DVM)中。...

    DexClassLoader自定义加载Assets目录下的dex、jar文件

    DexClassLoader是ClassLoader的一个子类,它的主要任务是加载.dex或.jar文件中的类。在Android中,通常每个应用都有一个默认的ClassLoader,它会加载APK内的classes.dex文件。然而,如果我们需要在运行时加载额外的....

    在Java的反射中,Class.forName和Class

    如果类还未加载,它会通过当前线程的上下文类加载器(Context Class Loader)来加载。 2. **类初始化**:除了加载类,`forName`还会执行类的初始化。这意味着静态块会被执行,静态变量会被初始化。 然而,`...

    深入探讨 Java 类加载器

    线程上下文类加载器(Thread Context ClassLoader)是一个特殊的角色,它允许在多线程环境中控制类的加载。每个线程都有一个与之关联的类加载器,可以通过Thread.currentThread().getContextClassLoader()获取。这在...

    Android内存加载Dex文件示例代码

    Android中的类加载主要由ClassLoader完成,它遵循双亲委托模型,即先尝试从父ClassLoader加载,如果找不到则递归到子ClassLoader。在默认情况下,系统会使用PathClassLoader加载应用程序的.dex文件。 为了在内存中...

    Spring中使用classpath加载配置文件浅析

    如果当前线程的ClassLoader无法获取到资源,Spring会转而使用加载org.springframework.util.ClassUtils类的ClassLoader。 在Spring加载配置文件时,我们需要注意几个关键点: 1. **不使用通配符**:当配置文件路径...

    Android动态加载(下)——加载已安装APK中的类和资源

    Android系统默认使用DexClassLoader来加载应用中的类,但如果我们想加载外部APK中的类,我们需要自定义ClassLoader。首先,我们需要获取到目标APK的路径,这可以通过Context.getPackageCodePath()或者File类来完成。...

    android动态加载jar

    在Android开发中,动态加载JAR(Java Archive)...总结,Android动态加载JAR是一种强大的技术,能带来诸多好处,但同时也需要注意安全和兼容性问题。通过合理利用DexClassLoader,开发者可以构建更灵活、可扩展的应用。

    Java类加载机制学习1

    线程上下文类加载器(Thread Context ClassLoader)是Java提供的一种机制,允许线程在运行时指定一个类加载器,确保类由同一个类加载器加载。这对于应用程序服务器和插件系统尤其有用,因为它允许组件使用自己的类...

Global site tag (gtag.js) - Google Analytics