`
ccr1988
  • 浏览: 35314 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jvm解析二(自定义加载器)

阅读更多
自定义加载器<code>
3个类LoaderTest01.java, LoaderTest02.java,MyClassLoader.java
1, MyClassLoader 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader  extends ClassLoader{
	
	private String name;
	private String path;
    private final String fileType=".class";
    public MyClassLoader(String name){
    	super();
    	this.name=name;
    }
   public MyClassLoader(ClassLoader parent,String name){
	   super(parent);
	   this.name=name;
   }
	@Override
	public String toString() {
		
		return this.name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public String getFileType() {
		return fileType;
	}
	
	private byte[] loadClassData(String name) {
       InputStream in=null;
       byte [] data=null;
       ByteArrayOutputStream bs=null;
       try{
    	   System.out.println("name="+this.name);
    	   this.name=this.name.replace(".", "\\");
           in=new FileInputStream(new File(path+name+fileType));
           bs=new ByteArrayOutputStream();
           int k=0;
           while((k=in.read())!=-1){
        	   bs.write(k);
           }
           data=bs.toByteArray();
       }catch(Exception e){
    	 e.printStackTrace();   
       }finally{
    	   try {
    		in.close();
			bs.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       }
       
       return data;
    }
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		byte [] data=this.loadClassData(name);
		
		return this.defineClass(name, data, 0,data.length);
	}
	
     public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
    	 MyClassLoader loader01=new MyClassLoader("loader01");
    	 loader01.setPath("d:\\loader\\lib1\\");
    	 
    	 MyClassLoader loader02=new MyClassLoader(loader01,"loader02");
    	 loader02.setPath("d:\\loader\\lib2\\");
    	 
    	 MyClassLoader loader03=new MyClassLoader(null,"loader03");
    	 loader03.setPath("d:\\loader\\otherlib3\\");
    	 
    	 load(loader02);
    	 load(loader03);
     }
   
     public static void load(ClassLoader loader) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
    	 Class c=loader.loadClass("LoaderTest01");
         Object object=c.newInstance();
     }
}

2, LoaderTest01
public class LoaderTest01 {

	public LoaderTest01() {
	   System.out.println("LoaderTest01 is loader by :"+this.getClass().getClassLoader());
	   new LoaderTest02();
	}

}

3, LoaderTest02
public class LoaderTest02 {

	public LoaderTest02() {
		   System.out.println("LoaderTest02 is loader by :"+this.getClass().getClassLoader());

	}

}

第一种情况文件按照下面位置放置

运行结果如下:

分析:当执行load(loader02)这句语句的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,发现没有,接着由loader01去加载,loader01加载的时候找到文件执行接下操作,而LoaderTest01里主动使用了new LoaderTest02(), LoaderTest02也会根据上面的方式去找,跟LoaderTest01结果是一样的。
     当执行load(loader03)这句语句的时候,由于父类加载器是null默认为根加载器,根加载器会去sun.boot.class.path的里面去找没有找到,最后由loader3自己去加载。
第二种情况文件按照下面位置放置

运行结果如下:

分析:当执行load(loader02)的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,发现没有,接着由loader01去加载,loader01加载的时候找到文件执行接下操作,而LoaderTest01里主动使用了new LoaderTest02(), LoaderTest02也会执行上面同样的步骤, 但是LoaderTest01和LoaderTest02位于2个不同的加载器空间下,而他们之间是互相不可见的(他们的父子关系并不是继承,也有可能是组合,但是他们都是系统加载器的子类,对系统加载器里的资源都是共享的),所以在Loader01加载器加载的时候无法获取LoaderTest02
第三种情况:

运行结果如下:

分析:当执行load(loader02)的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,并在当前目录下发现了这2个类,并执行操作,前2个加载器均为系统加载器,虽然lib1和lib2下2个文件在不同的类加载器空间下,但是实际执行并不需要它们,在系统一级已经执行完毕,而第三个,当执行load(loader03)的时候,父加载器null默认为根加载器,根加载器无法在相应的目录里找到相应的文件,于是交由其他加载器实现,而此时loader03加载器在相应的otherlib3下也无法找到相应的文件于是报错。
  • 大小: 14.8 KB
  • 大小: 3 KB
  • 大小: 16.3 KB
  • 大小: 6.5 KB
  • 大小: 16.9 KB
  • 大小: 3.9 KB
1
0
分享到:
评论

相关推荐

    自定义类加载器实现自定义加载

    在Java编程语言中,类加载器(ClassLoader)是运行时环境...理解类加载机制并正确实现自定义加载器是提升Java应用开发能力的重要一步。在实际项目中,合理利用类加载器可以解决很多复杂问题,比如模块化、动态更新等。

    自定义Java类加载器

    - **安全沙箱**:每个加载器都有自己的命名空间,可以通过自定义加载器限制代码访问权限。 - **插件系统**:插件有自己的类加载器,使得插件可以独立于主程序加载和卸载。 在编写`MyClassLoader`时,需要注意的是,...

    jvm字节码自动加载

    在Java虚拟机(JVM)中,字节码自动加载是一项关键...总之,JVM字节码自动加载是一个涉及类加载器、双亲委派模型以及字节码解析和验证的复杂过程。掌握这些知识有助于我们更好地理解和调试Java应用程序,提升开发效率。

    JVM类加载器说明文档

    2. 安全性问题:如果允许用户自定义类加载器任意加载代码,可能会破坏系统的安全策略,因为类加载器可以加载不受限制的代码。 3. 单例模式的实现:在多线程环境中,如果每个线程都有自己的类加载器,可能导致单例...

    JVM:类加载器子系统.pdf

    综上所述,JVM的类加载器子系统是复杂且精细的,它涉及到了类的加载、验证、准备、解析和初始化等多个环节。而类加载器作为类加载过程中的关键组件,其设计使得Java应用程序能够灵活地加载和运行各种不同的类文件。...

    JVM类加载机制详细讲解

    例如,当我们尝试加载 `java.lang.Object` 类时,首先会由启动类加载器加载,如果它找不到,会继续交给扩展类加载器,接着是系统类加载器,最后才会由用户自定义的类加载器尝试加载。 1.3 类加载双亲委派示例 为了...

    JVM实战-JVM类加载机制案例分析

    2. **类加载器及类加载器的委托机制**:JVM中有三种内置的类加载器,分别是启动类加载器、扩展类加载器和应用类加载器。此外,还可以自定义类加载器。类加载器之间遵循委托机制,即下级类加载器先请求上级类加载器...

    Java加壳源码-自定义类加载器

    在Java中,类加载器是负责加载类到JVM(Java虚拟机)的核心组件。自定义类加载器允许开发者根据特定需求定制类的加载逻辑,例如在加载过程中进行加密、混淆等操作,以增加程序的保护层。 本文将深入探讨Java加壳...

    jvm 加载class文件

    Java程序的运行依赖于类加载器将`.class`文件加载到JVM中,并对其进行验证、准备和解析等步骤,最终使类能够在JVM中执行。 #### 三、Class文件的加载过程 Java类的加载过程主要可以分为以下几个阶段: 1. **加载...

    JAVA-JVM-01类加载机制

    《JAVA-JVM-01类加载机制》 Java虚拟机(JVM)是Java程序运行的基础,其中类加载机制是其核心组成部分。...自定义类加载器则提供了扩展JVM类加载功能的可能,使得开发者能够根据需求加载非标准路径或网络上的类。

    《 从NoSuchMethodError看jvm编译和class加载方式》的测试项目代码

    JVM(Java虚拟机)采用“双亲委派模型”加载类,即当一个类被加载时,它会首先尝试由启动类加载器(Bootstrap ClassLoader)加载,如果该类不在启动类加载器的路径中,则会委托给扩展类加载器(Extension ...

    深入解析Java类加载器及其工作机制

    Java 类加载器是 Java 运行时环境中不可或缺的组成部分,负责将 .class 文件加载到 JVM 中。理解类加载器的工作原理对于深入掌握 Java 语言及其运行机制至关重要。本文将详细探讨 Java 类加载器的概念、类型以及工作...

    自定义类加载代码

    在Java编程语言中,类加载器(ClassLoader)是运行时环境的重要组成部分,它负责查找和加载类的字节码文件到Java虚拟机(JVM)中。本篇将深入探讨自定义类加载器的实现、双亲委派模型以及如何指定父类加载器。 首先...

    java类加载器

    - **特点**:如果应用程序中没有自定义类加载器,通常就是使用此加载器。 #### 六、示例代码解析 以下是一个简单的示例代码,演示了如何获取不同级别的类加载器: ```java @Test public void testClassLoader1()...

    类加载器代码

    类加载器是Java虚拟机(JVM)的重要组成部分,它负责将类的字节码从文件系统或网络中加载到JVM中,并转换为运行时的java.lang.Class对象。类加载器不仅涉及程序的启动,还关系到类的动态加载、类间的隔离以及安全性...

    JVM(三):类加载机制(类加载过程和类加载器)1

    用户可以通过自定义类加载器来控制字节流的获取方式,增加了程序的灵活性。 2. **验证(Verification)**: 验证阶段是链接过程的第一步,目的是确保加载的类文件信息符合JVM规范且不会危害虚拟机的安全。验证包括...

    jvm-profiler,jvm分析器向kafka、控制台输出或自定义报告器发送度量.zip

    《JVM Profiler:深入解析与应用》 在IT领域,优化Java应用程序的性能是至关重要的,而JVM(Java虚拟机)作为Java程序运行的基础,其内部运作机制的了解和调优对于提升效率至关重要。"jvm-profiler"是一个开源项目...

    JVM类加载分析

    四、自定义类加载器 开发者可以通过继承java.lang.ClassLoader类来创建自己的类加载器,实现特定的加载策略。例如,可以从网络上加载类,或者实现热部署等高级功能。 五、类加载的工具与实践 在Java开发中,类...

    Java的类加载器

    Java的类加载器是Java虚拟机(JVM)的核心组件之一,它负责将类的字节码文件从文件系统或网络中加载到JVM中,然后进行校验、解析和初始化,使得Java程序能够运行。类加载器的概念是Java动态加载和运行时类重定义的...

Global site tag (gtag.js) - Google Analytics