Java安全——JVM类加载器(1),啃下这些Framework技术笔记

这篇具有很好参考价值的文章主要介绍了Java安全——JVM类加载器(1),啃下这些Framework技术笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

正文

System.out.println(classloader2);

}

}

运行结果如下所示,我们可以发现ExtClassLoader的父类加载器为null,原因是BootStrapClassLoader由C实现,无法载Java代码中体现其类之间的关系,但是在实际使用过程中ExtClassLoader确实会委托顶级类加载器BootStrapClassLoader进行类加载,代码实现如下

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

查看ClassLoader类中的loadClass方法,其中有一块逻辑判断了parent是否为null,如果为null就直接调用findBootstrapClassOrNull方法。

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

0x2 类方法及属性

在ClassLoader及其子类中有几个比较重要的方法以及属性。ClassLoader中主要实现了loadClass方法,该方法采用双亲委派机制。

public abstract class ClassLoader {

private final ClassLoader parent;

public Class<?> loadClass(String name) throws ClassNotFoundException {}

protected Class<?> findClass(String name) throws ClassNotFoundException {}

protected final Class<?> findLoadedClass(String name) {}

protected final Class<?> defineClass(byte[] b, int off, int len){}

protected final void resolveClass(Class<?> c) {}

}

1.loadClass(String)方法加载指定的类,不建议用户重写

2.findLoadedClass(String) 方法检查这个类是否被加载过

3.findClass(String) 方法用来加载类

4.defineClass(byte[] b,int off,int len)方法是用来将byte字节流解析成JVM能够识别的Class对象

5.resolveClass(Class) 方法用来链接指定的类,主要是对字节码进行验证,为类变量分配内存并设置初始值同时将字节码文件中的符号引用转换为直接引用

public class URLClassLoader extends SecureClassLoader implements Closeable {

private final URLClassPath ucp;

}

URLClassLoader类中的ucp属性一般存放类加载路径,在双亲委派机制中每一个ClassLoader类都会对应它负责的加载路径。再者比较重要的是ClassLoader类中的关于类加载的方法。

0x03 双亲委派机制


双亲委派机制是Java类加载的核心,该机制一定程度的保证了类加载的安全性。简单来讲这个机制就是“当有载入类的需求时,类加载器会先请示父加载器帮忙载入,如果没有父加载器那么就使用BootStrapClassLoader进行加载,如果所有的父加载器都找不到对应的类,那么才由自己依照自己的搜索路径搜索类,如果还是搜索不到,则抛出ClassNotFoundException

0x1 双亲委派结构

在Java JDK中的类加载器结构如下图所示,BootstrapClassLoader为根加载器、ExtClassLoader为扩展类加载器、AppClassLoader为应用类加载器。其结构如下所示,需要注意的是他们这几个类之间的关系为依赖关系,并不是继承关系。

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

其中User1ClassLoader可以为应用自己设计的类加载器,并设置AppClassLoader为父加载器,这样就可以使用双亲委派机制。

0x2 代码实现

那么关于双亲委派机制代码上的实现也很简单,根据功能描述写对应的if else分支即可。一般在ClassLoader子类中

protected Class<?> loadClass(String name, boolean resolve)

throws ClassNotFoundException

{

synchronized (getClassLoadingLock(name)) {

// First, check if the class has already been loaded

Class<?> c = findLoadedClass(name);

if (c == null) { //判断是否已经加载该类

long t0 = System.nanoTime();

try {

if (parent != null) {//如果有父类,尝试让父类去加载

c = parent.loadClass(name, false);

} else {

c = findBootstrapClassOrNull(name);//如果没有父类,尝试使用根装载器加载

}

} catch (ClassNotFoundException e) { }

if (c == null) {

// If still not found, then invoke findClass in order

// to find the class.

long t1 = System.nanoTime();

c = findClass(name);//这块需要自定义,比如自己写的类装载器就可以在这里实现类装载功能

// this is the defining class loader; record the stats

sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

sun.misc.PerfCounter.getFindClasses().increment();

}

}

if (resolve) {

resolveClass©;//链接已经装载的类

}

return c;

}

}

0x04 自定义类加载器


同一个类代码如果被不同的类加载器加载,那么在当前JVM中他们是两个不同的类。

0x1 遵循双亲委派机制

1.继承java.lang.ClassLoader

2.重写父类的findClass方法

loadClass方法已经实现了双亲委派功能,如果我们再去覆盖loadClass函数就会破坏双亲委派机制。并且JDK已经在loadClass方法中帮我们实现了ClassLoader搜索类的算法,当在loadClass方法中搜索不到类时,loadClass方法就会调用findClass方法来搜索类,所以我们只需重写该方法即可。

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

0x2 破坏双亲委派机制

双亲委派机制主要依赖于ClassLoader类中的loadclass函数实现逻辑,如果直接在子类中重写loadClass方法,就可以破坏双亲委派机制。目前存在的一些组件,其类加载机制不符合双亲委派也很正常。那么可能有小伙伴就很迷糊了,到底是要遵守还是要破坏呢?应该根据需求,特殊情况特殊对待,大佬们也总结过几种应用场景,梳理如下

1. Tomcat类加载机制

首先说明双亲委派机制的缺点是,当加载同个jar包不同版本库的时候,该机制无法自动选择需要版本库的jar包。特别是当Tomcat等web容器承载了多个业务之后,不能有效的加载不同版本库。为了解决这个问题,Tomcat放弃了双亲委派模型。

当时分析Shiro反序列化的时候,遇到了Tomcat的类加载器重写了loadClass函数,从而没有严格按照双亲委派机制进行类加载,这样才能实现加载多个相同类,相当于提供了一套隔离机制,为每个web容器提供一个单独的WebAppClassLoader加载器。

Tomcat加载机制简单讲,WebAppClassLoader负责加载本身的目录下的class文件,加载不到时再交给CommonClassLoader加载,这和双亲委派刚好相反。

2. OSGI模块化加载机制

不再是双亲委派的树桩结构,而是网状结构,没有固定的委派模型,只有具体使用某个package或者class时,根据package的导入导出的定义来构造bundle之间的委派和依赖。这块内容也打算单独写,vCenter部署及类加机制很大程度上依赖该技术,这里先挖个坑。

3. JDBC类加载机制

这里双亲委派的缺点是父加载器无法使用子加载器加载需要的类,这个使用场景就在JDBC中出现了。

以往JDBC的核心类在rt.jar中,由根加载器加载,然而现在核心类在不同厂商实现的jar包中,根据类加载机制,如果A类调用B类,则B类由A类的加载器加载,这也就意味着根加载器要加载jar包下的类,很显然这一操作违背了双亲委派机制。

为了让父加载器调用子加载器加载需要的类,JDBC使用了Thread.currentThread().getContextClassLoader()得到线程上下文加载器来加载Driver实现类。

0x3 加载加密字节码

为了更深入的了解ClassLoader的工作流程,打算自己写一个加载Class密文件。首先编写加解密函数,将编译好的class文件通过encryptfile函数加密。

package myclassloadertest;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import java.io.*;

public class FileUtils {

private static final int ZERO = 0;

private static final int ONE = 1;

private static String derectory ;

private static String key = “aaaabbbbccccdddd”;

private static String ivParameter = “AAAABBBBCCCCDDDD”;

public FileUtils (String path){

derectory = path;

}

public static byte[] doFile(int code, File file, String key, String ivParameterm, String filename) throws Exception {

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(

file));

byte[] bytIn = new byte[(int) file.length()];

bis.read(bytIn);

bis.close();

byte[] raw = key.getBytes(“ASCII”);

SecretKeySpec skeySpec = new SecretKeySpec(raw, “AES”);

Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”);

IvParameterSpec iv = new IvParameterSpec(ivParameterm.getBytes());

if (0 == code) {

cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

} else if (1 == code) {

cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

}

byte[] bytOut = cipher.doFinal(bytIn);

File outfile = new File(derectory + “/” + filename);

BufferedOutputStream bos = new BufferedOutputStream(

new FileOutputStream(outfile));

bos.write(bytOut);

bos.close();

return bytOut;

}

public static void encryptfile(File file, String key, String ivParameter, String filename) throws Exception {

doFile(ZERO, file, key, ivParameter, filename);

}

public static byte[] decryptfile(File file, String key, String ivParameter, String filename) throws Exception {

return doFile(ONE, file, key, ivParameter, filename);

}

public static byte[] loadfile(String name) throws Exception {

File file = new File(derectory + name.replace(‘.’, ‘/’) + “.class”);

return decryptfile(file, key, ivParameter, “decrypt_tmp_file”);

}

public static void main(String[] args) {

try {

File file = new File(derectory + “myclassloadertest/Test.class”);

String fileName = “myclassloadertest/TestCrypt.class”;

encryptfile(file, key, ivParameter, fileName);

} catch (Exception e) {

e.printStackTrace();

}

}

}

自己编写的classloader只需要使用其中loadfile函数就可以找到文件并自动解密。自定义ClassLoader代码如下

package myclassloadertest;

public class MyClassLoader extends ClassLoader{

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!文章来源地址https://www.toymoban.com/news/detail-861495.html

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

Java安全——JVM类加载器(1),啃下这些Framework技术笔记,2024年程序员学习,java,安全,jvm

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
[外链图片转存中…(img-ybXlsMn6-1713335612881)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

到了这里,关于Java安全——JVM类加载器(1),啃下这些Framework技术笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM——类加载与字节码技术—类文件结构

      由源文件被编译成字节码文件,然后经过类加载器进行类加载,了解类加载的各个阶段,了解有哪些类加载器,加载到虚拟机中执行字节码指令,执行时使用解释器进行解释执行,解释时对热点代码进行运行期的编译处理。    根据下面规范,魔数,两个版本,常量池信息

    2024年02月11日
    浏览(40)
  • JVM:Java类加载机制

            加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始, 这是为了支持Java语言的运行时绑定特性(也称为动态绑定或晚期绑定)。

    2024年01月21日
    浏览(38)
  • [JVM] Java类的加载过程

    在Java中,类的加载是指在程序运行时将类的二进制数据加载到内存中,并转化为可以被JVM执行的形式的过程。类的加载过程主要包括以下几个步骤: 加载 (Loading):通过类的全限定名,使用类加载器将类的二进制数据加载到JVM中。类加载器会根据类的名称找到对应的字节码

    2024年01月16日
    浏览(36)
  • JVM 虚拟机 ----> Java 类加载机制

    一、概述 类是在运行期间第一次使用时,被类加载器动态加载至 JVM 。JVM不会一次性加载所有类。因为如果一次性加载,那么会占用很多的内存 二、类的生命周期 类的生命周期包含以下 七 个阶段: 加载(Loading) 验证(Verification) 准备(Preparation) 解析(Resolution) 初始化

    2024年02月07日
    浏览(41)
  • 【Jvm】Java类加载机制是什么?

    什么是类的加载? 类的生命周期? 类加载器是什么? 双亲委派机制是什么? JVM将class文件字节码文件加载到内存中, 并将这些静态数据转换成方法区中的运行时数据结构,在堆(并不一定在堆中,HotSpot在方法区中)中生成一个代表这个类的java.lang.Class 对象,作为方法区类数

    2024年02月11日
    浏览(41)
  • p7付费课程笔记:jvm基础知识、字节码、类加载器

    机器语言-编程语言-高级语言(java,c++,Go,Rust等) 面向过程–面向对象-面向函数 java是一种面向对象、静态类型、编译执行,有VM(虚拟机)/GC和运行时、跨平台的高级语言。重点:VM(虚拟机)/GC(Garbage Collector)和运行时、跨平台。 跨平台步骤:字节码文件被虚拟机加载(

    2024年02月10日
    浏览(41)
  • 【JAVA基础】JVM之类加载--双亲委派机制

    1. 类加载的过程 描述: 我们写的 .java 文件通过编译成字节码文件 .class 文件,然后再通过我们的类加载器:Class Loader,反射以后,类模板存在方法区,把实例化的对象存在堆里; 看图: 对象的hashcode值 解释: 从图中我们可以看出,从同一个类模板new出来三个对象(实例化

    2024年01月23日
    浏览(45)
  • Java JVM类加载阶段 双亲委派模式

    加载 将类的字节码载入方法区中,内部采用 C++ 的 instanceKlass 描述 java 类,它的重要 field 有: _java_mirror 即 java 的类镜像,例如对 String 来说,就是 String.class,作用是把 klass 暴露给 java 使用 _super 即父类 _fields 即成员变量 _methods 即方法 _constants 即常量池 _class_loader 即类加载器

    2024年01月25日
    浏览(46)
  • 云计算:云计算安全性有哪些?_云计算技术的安全性,这些知识你必须拿下

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新网络安全全套学习资料》

    2024年04月23日
    浏览(47)
  • 【Java】JVM执行流程、类加载过程和垃圾回收机制

    JVM,就是Java虚拟机,Java的的程序都是运行在JVM当中。 程序在执行之前先要把java源代码转换成字节码(class文件),JVM 首先需要把字节码通过一定的方(类加载器(ClassLoader)) 把文件加载到内存中的运行时数据区(Runtime Data Area) ,而字节码文件是 JVM 的一套指令集规范,并

    2024年02月16日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包