创建简单 class 文件时方法签名的非法常量池索引
Illegal constant pool index for method signature when creating a simple class file
我想创建一个生成 Java 字节码的简单编译器。为了生成代码,我使用了 Apache BCEL 库。
但是,我未能使用不执行任何操作的 main 方法创建简单的 class。我使用以下代码(我知道它是 Scala,但这并不重要,稍后您会看到)生成 class 文件:
private def generateClassFile(): Unit =
{
// JVM tutorial: https://commons.apache.org/proper/commons-bcel/manual/jvm.html
val interfaces: Array[String] = new Array(0);
classFactory = new ClassGen(
"MiniPascal",
"java.lang.Object",
null,
Const.ACC_PUBLIC | Const.ACC_SUPER,
interfaces
);
val mainConstantPool: ConstantPoolGen = new ConstantPoolGen();
val mainMethod = generateMainMethod(mainConstantPool);
classFactory.addMethod(mainMethod.getMethod());
}
private def generateMainMethod(mainConstantPool): MethodGen =
{
val instructions = new InstructionList();
instructions.append(InstructionConstants.NOP);
mainConstantPool.addNameAndType("main", "([java/lang/String;)V");
val methodArgumentNames = Array("args");
val methodArgumentTypes: Array[Type] = Array(new ArrayType(Type.STRING, 1));
val mainMethod: MethodGen = new MethodGen(
Const.ACC_PUBLIC | Const.ACC_STATIC,
Type.VOID,
methodArgumentTypes,
methodArgumentNames,
"main", "MiniPascal",
instructions,
mainConstantPool
);
return mainMethod;
}
private def saveClassFile(): Unit =
{
val classFile: JavaClass = classFactory.getJavaClass();
classFile.dump("MiniPascal.class");
//println(classFile.toString());
}
当 运行 程序生成 class 文件时,但是当执行 java MiniPascal
时,我得到以下异常:
java.lang.ClassFormatError: Illegal constant pool index 4 for method signature in class file MiniPascal
我阅读了 Java 字节码,知道常量池大约占 class 文件内容的 60%,并存储所有文字的名称,但我还没有弄清楚出异常的情况呢。
期待您的建议。感谢您的帮助!
您正在创建您自己的空常量池,您不与 class 关联,使用行:
val mainConstantPool: ConstantPoolGen = new ConstantPoolGen();
因此,尽管您将方法签名添加到常量池中,但它不起作用,因为常量池从未添加到 class 文件中。
首先创建常量池并将其作为最后一个参数传递给 ClassGen
构造函数,或者从 classFactory.getConstantPool()
.
初始化 mainConstantPool
我想创建一个生成 Java 字节码的简单编译器。为了生成代码,我使用了 Apache BCEL 库。
但是,我未能使用不执行任何操作的 main 方法创建简单的 class。我使用以下代码(我知道它是 Scala,但这并不重要,稍后您会看到)生成 class 文件:
private def generateClassFile(): Unit =
{
// JVM tutorial: https://commons.apache.org/proper/commons-bcel/manual/jvm.html
val interfaces: Array[String] = new Array(0);
classFactory = new ClassGen(
"MiniPascal",
"java.lang.Object",
null,
Const.ACC_PUBLIC | Const.ACC_SUPER,
interfaces
);
val mainConstantPool: ConstantPoolGen = new ConstantPoolGen();
val mainMethod = generateMainMethod(mainConstantPool);
classFactory.addMethod(mainMethod.getMethod());
}
private def generateMainMethod(mainConstantPool): MethodGen =
{
val instructions = new InstructionList();
instructions.append(InstructionConstants.NOP);
mainConstantPool.addNameAndType("main", "([java/lang/String;)V");
val methodArgumentNames = Array("args");
val methodArgumentTypes: Array[Type] = Array(new ArrayType(Type.STRING, 1));
val mainMethod: MethodGen = new MethodGen(
Const.ACC_PUBLIC | Const.ACC_STATIC,
Type.VOID,
methodArgumentTypes,
methodArgumentNames,
"main", "MiniPascal",
instructions,
mainConstantPool
);
return mainMethod;
}
private def saveClassFile(): Unit =
{
val classFile: JavaClass = classFactory.getJavaClass();
classFile.dump("MiniPascal.class");
//println(classFile.toString());
}
当 运行 程序生成 class 文件时,但是当执行 java MiniPascal
时,我得到以下异常:
java.lang.ClassFormatError: Illegal constant pool index 4 for method signature in class file MiniPascal
我阅读了 Java 字节码,知道常量池大约占 class 文件内容的 60%,并存储所有文字的名称,但我还没有弄清楚出异常的情况呢。
期待您的建议。感谢您的帮助!
您正在创建您自己的空常量池,您不与 class 关联,使用行:
val mainConstantPool: ConstantPoolGen = new ConstantPoolGen();
因此,尽管您将方法签名添加到常量池中,但它不起作用,因为常量池从未添加到 class 文件中。
首先创建常量池并将其作为最后一个参数传递给 ClassGen
构造函数,或者从 classFactory.getConstantPool()
.
mainConstantPool