All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.bytekit.asm.ClassMetaClassWriter Maven / Gradle / Ivy

package com.alibaba.bytekit.asm;

import com.alibaba.bytekit.asm.meta.ClassMeta;
import com.alibaba.bytekit.utils.ClassLoaderUtils;
import com.alibaba.deps.org.objectweb.asm.ClassReader;
import com.alibaba.deps.org.objectweb.asm.ClassWriter;

/**
 * 基于 ClassMeta 实现的 ClassWriter,避免加载类
 * 
 * @author hengyunabc 2023-03-16
 *
 */
public class ClassMetaClassWriter extends ClassWriter {
    private ClassLoader classLoader;

    public ClassMetaClassWriter(int flags, ClassLoader loader) {
        this(null, flags, loader);
    }

    public ClassMetaClassWriter(ClassReader classReader, int flags, ClassLoader loader) {
        super(classReader, flags);
        // TODO 对 null loader的处理是否准确
        this.classLoader = ClassLoaderUtils.wrap(loader);
    }

    /*
     * 注意,为了自动计算帧的大小,有时必须计算两个类共同的父类。
     * 缺省情况下,ClassWriter将会在getCommonSuperClass方法中计算这些,通过在加载这两个类进入虚拟机时,使用反射API来计算。
     * 但是,如果你将要生成的几个类相互之间引用,这将会带来问题,因为引用的类可能还不存在。
     * 在这种情况下,你可以重写getCommonSuperClass方法来解决这个问题。
     * 
     * 
     * 1. 采用尝试用 ClassLoader#getResource 的方式来读取 .class 文件,再计算 CommonSuperClass
     * 2. 因为计算过程中,可能需要一直向上查找 super 类的 .class 文件,中间可能失败
     * 3. 失败后则回退到原来的 ClassWriter#getCommonSuperClass(String, String) ,但ClassLoader是指定的。本类重写了 getClassLoader() 函数
     * 
* */ @Override protected String getCommonSuperClass(String type1, String type2) { byte[] type1Bytes = ClassLoaderUtils.readBytecodeByName(classLoader, type1); if (type1Bytes == null) { return super.getCommonSuperClass(type1, type2); } byte[] type2Bytes = ClassLoaderUtils.readBytecodeByName(classLoader, type2); if (type2Bytes == null) { return super.getCommonSuperClass(type1, type2); } ClassMeta classMeta1 = ClassMeta.fromByteCode(type1Bytes, classLoader); ClassMeta classMeta2 = ClassMeta.fromByteCode(type2Bytes, classLoader); if (classMeta1.isAssignableFrom(classMeta2)) { return type1; } if (classMeta2.isAssignableFrom(classMeta1)) { return type2; } if (classMeta1.isInterface() || classMeta2.isInterface()) { return "java/lang/Object"; } else { do { classMeta1 = classMeta1.getSuperclass(); if (classMeta1 == null) { // TODO 是直接返回 "java/lang/Object",还是尝试用指定 classLoader 查找 return getCommonSuperClass(type1, type2); } } while (!classMeta1.isAssignableFrom(classMeta2)); return classMeta1.getInternalClassName(); } } /** * 重写获取 classLoader 函数,原来的逻辑是直接用 ClassMetaClassWriter 的 classLoader */ @Override protected ClassLoader getClassLoader() { return classLoader; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy