Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating .class file for JVM

I am working on a project that requires me to generate a java ".class" file on the go that can be later on compiled on the JVM. After learning and working with MSIL (Microsoft IL) which is also a stack based intermediate programming language, the following are the problems I am facing :

  1. As compared to the IL (for C# or VB) the java bytecode in ".class" file contains information in a structured manner and as far as i could understand the file, it contains the metadata apart from the program data, is it true?? Can i generate the same in a template form for every class file??
  2. Is it compulsory to generate the class file in binary??

I have refered to " Programming for the Java™ Virtual Machine By Joshua Engel " but it has not served my purpose as I have already learned about the JVm instruction set.

Can anybody please help me with this?? All help will be highly appreciated. An example for generating a simple class file would be really helpful as i could not locate a single 1 yet.

like image 883
Raghav Bali Avatar asked Nov 25 '09 16:11

Raghav Bali


1 Answers

Example using the ASM bytecode library converted to work with .NET using the IKVM Java-to-.NET compiler:

hello.cs:

using System;
using System.IO;
using org.objectweb.asm;

namespace test.helloWorld
{
    public class helloDump
    {

        public static byte[] dump ()
        {

            ClassWriter cw = new ClassWriter(0);
            MethodVisitor mv;

            cw.visit(Opcodes.__Fields.V1_6, Opcodes.__Fields.ACC_PUBLIC + Opcodes.__Fields.ACC_SUPER, "hello", null, "java/lang/Object", null);

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

            mv = cw.visitMethod(Opcodes.__Fields.ACC_PUBLIC + Opcodes.__Fields.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
            mv.visitCode();
            mv.visitFieldInsn(Opcodes.__Fields.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitLdcInsn("Hello World!");
            mv.visitMethodInsn(Opcodes.__Fields.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
            mv.visitInsn(Opcodes.__Fields.RETURN);
            mv.visitMaxs(2, 1);
            mv.visitEnd();

            cw.visitEnd();

            return cw.toByteArray();
        }

        public static void Main(string[] args)
        {
            FileStream helloWorldFile = new FileStream("hello.class", FileMode.Create);
            byte[] helloWorldClass = dump();
            helloWorldFile.Seek(0, SeekOrigin.Begin);
            helloWorldFile.Write(helloWorldClass, 0, helloWorldClass.Length);
        }
    }
}

commands:

$ ikvmc -out:org.objectweb.asm.dll -target:library -version:3.2.0.0 asm-3.2.jar
$ mcs -r:org.objectweb.asm.dll  hello.cs
$ mono hello.exe
$ ls hello.class
$ java hello
like image 100
Stobor Avatar answered Oct 25 '22 20:10

Stobor