I write a simple program using Java ASM to generate the byte code which is generated by compiling the following class.
public class Main {
public static void main(String[] args) {
System.out.println("Test");
}
}
The code I wrote to generate the bytecode for this class is given below.
public class CodeGenerator {
public void generateClass()
{
ClassWriter cw=new ClassWriter(Opcodes.NULL);
FieldVisitor fv;
MethodVisitor mv;
cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Main", null, "java/lang/Object", null);
mv=cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.AALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
mv=cw.visitMethod(Opcodes.ACC_PUBLIC+ Opcodes.ACC_STATIC, "Main", "([Ljava/lang/String;)V", null, null);
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream");
mv.visitLdcInsn("Test");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
cw.visitEnd();
this.WriteClass(cw);
}
public void WriteClass(ClassWriter cw){
FileOutputStream fos;
try{
fos = new FileOutputStream("E:\\Acadamic\\Final year project\\ASM\\Main.class");
fos.write(cw.toByteArray());
fos.close();
}
catch (IOException ex){
Logger.getLogger(CodeGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This compiles successfully and when I try to run it, it gives the following error.
Exception in thread "main" java.lang.NoClassDefFoundError: main/class
Caused by: java.lang.ClassNotFoundException: main.class
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: main.class. Program will exit.
can any one please help me for avoid this error. If anyone can explain the cause to the error and how to avoid it, please be kind enough to help me.
Thank You.
Follow-up:
When I run it like java Main it gives the following error.
Exception in thread "main" java.lang.ClassFormatError: Field "out" in class Main
has illegal signature "Ljava/io/PrintStream"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: Main. Program will exit.
I don’t think your error is being caused by ASM. It looks like you simply called
javaincorrectly. You should call it like this:My guess is that you called it like this:
Update
There are three problems with your code.
Problem #1
The
ClassWriterconstructor accepts a bit mask of options. You passed itOpcodes.NULL. Although this may seem correct, you actually want to pass it0(Opcodes.NULLmeans something different).Problem #2
You are calling
AALOADin the constructor instead ofALOAD. TheAALOADinstruction loads an array element, whereasALOADloads a local variable.Problem #3
In your
Mainmethod, you forgot the semicolon afterLjava/io/PrintStream:You can save yourself some pain by taking advantage of ASM’s
Typeclass: