在使用asm包进行动态类加载的时候的打包问题

如图所示,开发时使用的jdk包下面的asm包,在进行打包时提示asm包不存在,打包方式使用如下:

目前提供两种解决方案:

1:修改打包方式,将jdk的包也打进去:

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> <compilerArguments> <verbose /> <!-- 将jdk的依赖jar打入项目中,这样项目中使用的jdk的依赖就尅正常使用 --> <bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar;${java.home}/lib/jsse.jar</bootclasspath> </compilerArguments> </configuration> </plugin> |

方案2:更换asm依赖,

在pom中引入如下内容

复制代码
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm</artifactId>
    <version>9.4</version>
</dependency>
在动态类加载中将  
复制代码
import jdk.internal.org.objectweb.asm.*;   替换为   import org.objectweb.asm.*;
动态类class加载完整类:
复制代码
package huilong.cloud.examCertificate.util;

import cn.afterturn.easypoi.excel.annotation.Excel;
import org.objectweb.asm.*;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;

/**
 * @Author: zzy
 * @Date: 2024/10/25/10:06
 * @Description:
 */
public class DynamicClassCreateUtil extends ClassLoader{
    public static Class<?> createClass(List<String> columnTitles){
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);

        String packageName = "huilong.cloud.examCertificate.util"; // 指定包名
        String className = "DynamicClass";
        String fullClasName = packageName + "." + className;
        String internalClassName = fullClasName.replace('.', '/');
//        String iExcelDataModelName = "cn/afterturn/easypoi/handler/inter/IExcelDataModel";
//        String iExcelModelName = "cn/afterturn/easypoi/handler/inter/IExcelModel";

        // 定义类
        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalClassName, null, "java/lang/Object", new String[]{});
//        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalClassName, null, "java/lang/Object", new String[]{iExcelDataModelName, iExcelModelName});

        // 添加构造器
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();

        // 添加字段
        for (int i = 0; i < columnTitles.size(); i++) {
            String header = columnTitles.get(i);
            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "get" + capitalize(header), "()Ljava/lang/String;", null, null);
            mv.visitCode();
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, internalClassName, header, "Ljava/lang/String;");
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();

            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "set" + capitalize(header), "(Ljava/lang/String;)V", null, null);
            mv.visitCode();
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            mv.visitFieldInsn(Opcodes.PUTFIELD, internalClassName, header, "Ljava/lang/String;");
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(1, 2);
            mv.visitEnd();
            // 定义一个带有@Excel注解的字段
            String fieldDesc = Type.getDescriptor(String.class); // String类型的描述符
            String annotationDesc = Type.getDescriptor(Excel.class);
            // 访问字段
            FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, header, fieldDesc, null, null);
            // 访问注解
            AnnotationVisitor av = fv.visitAnnotation(annotationDesc, true);
            av.visit("name", header); // 设置注解属性的值
            // 结束注解的访问
            av.visitEnd();
            // 结束字段的访问
            fv.visitEnd();

        }
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRowNum", "(I)V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ILOAD, 1);
        mv.visitVarInsn(Opcodes.ISTORE, 2);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 3);
        mv.visitEnd();
        // 结束类定义
        cw.visitEnd();
        byte[] byteArray = cw.toByteArray();
        // 创建自定义类加载器
        try {
            // 假设这是你的类字节码
            ByteArrayClassLoader classLoader = new ByteArrayClassLoader(byteArray);
            return classLoader.loadClass(fullClasName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    public static HashMap<String, String> objectToMap(Object obj) {
        if (obj == null) {
            throw new IllegalArgumentException("Object cannot be null");
        }

        HashMap<String, String> map = new HashMap<>();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(obj);
                map.put(field.getName(), value == null ? "" : value.toString());
            } catch (IllegalAccessException e) {
                throw new RuntimeException("字段转换失败 " + field.getName(), e);
            }
        }
        return map;
    }
}