Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The class file of the method content generated using Bytecode failed to load #490

Open
Milory opened this issue Sep 12, 2024 · 0 comments
Open

Comments

@Milory
Copy link

Milory commented Sep 12, 2024

I have been learning Javassist (VERSION: 3.30.2-GA)recently and have also learned how to use Bytecode content. I would like to write a simple introductory example, as follows:

    @Test
    @SneakyThrows
    @DisplayName("读取注解")
    public void test01() {
        // 创建 ClassPool 对象
        ClassPool pool = ClassPool.getDefault();

        // 创建新类
        CtClass ctClass = pool.makeClass("HelloWorld");

        // 创建新方法
        CtMethod ctMethod = new CtMethod(pool.get("java.lang.String"), "greet", new CtClass[]{}, ctClass);
        ctMethod.setModifiers(Modifier.PUBLIC);

        // 获取类的常量池
        ConstPool constPool = ctClass.getClassFile().getConstPool();

        // 创建 Bytecode 对象,关联常量池
        Bytecode bytecode = new Bytecode(constPool);

        // 生成字节码指令:将字符串 "Hello, World!" 加载到栈顶
        bytecode.addLdc("Hello, World!");

        // 添加返回指令
        bytecode.addOpcode(Opcode.ARETURN);

        // 将生成的字节码设置到方法中
        ctMethod.getMethodInfo().setCodeAttribute(bytecode.toCodeAttribute());

        // 将方法添加到类中
        ctClass.addMethod(ctMethod);

        Class<?> aClass = ctClass.toClass();
        Object object = aClass.newInstance();
        System.err.println(aClass.getDeclaredMethod("greet").invoke(object));

But I found that the execution failed, and the error exception message thrown is as follows:

javassist.CannotCompileException: by java.lang.ClassFormatError: Arguments can't fit into locals in class file HelloWorld

	at javassist.util.proxy.DefineClassHelper.toClass(DefineClassHelper.java:271)
	at javassist.ClassPool.toClass(ClassPool.java:1240)
	at javassist.ClassPool.toClass(ClassPool.java:1098)
	at javassist.ClassPool.toClass(ClassPool.java:1056)
	at javassist.CtClass.toClass(CtClass.java:1298)
	at org.lijin.javassist.test01.Bytecode06.test01(Bytecode06.java:61)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
Caused by: java.lang.ClassFormatError: Arguments can't fit into locals in class file HelloWorld
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:757)
	at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
	at javassist.util.proxy.DefineClassHelper$Java7.defineClass(DefineClassHelper.java:177)
	at javassist.util.proxy.DefineClassHelper.toClass(DefineClassHelper.java:260)
	... 8 more

So I used CtMethod. make() to regenerate the class file and compared the binary content of the file, and found that there were differences between the two files:

image

I don't know if there is a problem with my Bytecode example or if it is a bug. Looking forward to your reply

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant