How to programmatically generate .class files?

后端 未结 4 1356
迷失自我
迷失自我 2021-01-02 04:03

I would like to write a compiler for a toy-language for Java. I would like to generate runnable .class files. I was wondering what is the best library or tool available for

相关标签:
4条回答
  • 2021-01-02 04:27

    Easiest would be to translate your toy-language into valid .java source code using a preprocessor and then just compile it with javac. That's also the way Processing works.

    0 讨论(0)
  • 2021-01-02 04:36

    It sounds like you're looking for Apache BCEL:

    The Byte Code Engineering Library (Apache Commons BCEL™) is intended to give users a convenient way to analyze, create, and manipulate (binary) Java class files (those ending with .class).

    0 讨论(0)
  • 2021-01-02 04:41

    ASM and BCEL do basically similar things. I'd recommend ASM as it's much more supported, much smaller, and is up to date JDK-wise.

    0 讨论(0)
  • 2021-01-02 04:44

    JDK 1.6 has the ability to dynamically compile Java classes (see getSystemJavaCompiler). This can be used to compile Java from source without byte code manipulation or temporary files. We're doing this as a way to improve the performance of some reflection API code, but it will just as easily serve your purpose as well.

    Create a Java source file from a string containing the code:

       public class JavaSourceFromString extends SimpleJavaFileObject {
           final String code;
    
           JavaSourceFromString(String name, String code) {
               super(URI.create("string:///"
                                + name.replace('.','/')
                                + Kind.SOURCE.extension),
                     Kind.SOURCE);
               this.code = code;
           }
    
           @Override
           public CharSequence getCharContent(boolean ignoreEncodingErrors) {
               return code;
           }
       }
    
    // Use your favorite template language here, like FreeMarker
    static final String sourceCode = ""
            + "import org.example.MySomethingObject;"
            // DynamicStringGetter would define getString as a standard way to get
            // a String from an object
            + "public class GetStringDynamic implements DynamicStringGetter {\n" 
            + "    public String getString(Object o) {\n"
            + "        MySomethingObject obj = (MySomethingObject) o;\n"
            + "        return o.getSomething();\n"
            + "    }\n"
            + "}\n";
    
       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
       StandardJavaFileManager fileManager = 
           compiler.getStandardFileManager(null, null, null);
    
       List<JavaFileObject> files = new ArrayList<JavaFileObject>();
       files.add(new JavaSourceFromString("org.example.DynamicClass", sourceCode));
    
       compiler.getTask(null, fileManager, null, null, null, files).call();
    

    Then you load the newly created class files dynamically.

    Alternatively, use byte code manipulation (such as ASM) to create classes on the fly.

    As another alternative, there is the Scala CAFEBABE bytecode compilation library. I have not used it personally, but it seems geared more towards creating a new JVM language.

    As far as the parsing portion goes, Antlr should serve.

    0 讨论(0)
提交回复
热议问题