动态编译而不创建物理文件 [英] Dynamic Compiling Without Create Physical File

查看:126
本文介绍了动态编译而不创建物理文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照生成Java的教程进行操作通过Java编译器API动态生成类,代码是可行的,但我看到的是程序在编译后会创建一个类文件。

I follow the tutorial from Generating Java classes dynamically through Java compiler API, the code is work but what I see is the program will create a class file after compiling it.

import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.*;

public class Compiler {

    static final Logger logger = Logger.getLogger(Compiler.class.getName());
    static String sourceCode = "class HelloWorld{"
        + "public static void main (String args[]){"
        + "System.out.println (\"Hello, dynamic compilation world!\");"
        + "}"
        + "}";

    public void doCompilation() {

        SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject("HelloWorld", sourceCode);
        JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject};

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);

        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);

        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();

        CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, null, null, compilationUnits);

        boolean status = compilerTask.call();

        if (!status) {
            for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
                System.out.format("Error on line %d in %s\n", diagnostic.getLineNumber(), diagnostic);
            }
        }
        try {
            stdFileManager.close();
        } catch (IOException ex) {
            Logger.getLogger(Compiler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String args[]) {
        new Compiler().doCompilation();
    }
}

class DynamicJavaSourceCodeObject extends SimpleJavaFileObject {

    private String qualifiedName;
    private String sourceCode;

    protected DynamicJavaSourceCodeObject(String name, String code) {
        super(URI.create("string:///" + name.replaceAll("\\.", "/") + JavaFileObject.Kind.SOURCE.extension), JavaFileObject.Kind.SOURCE);
        this.qualifiedName = name;
        this.sourceCode = code;
    }

    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors)
        throws IOException {
        return sourceCode;
    }

    public String getQualifiedName() {
        return qualifiedName;
    }

    public void setQualifiedName(String qualifiedName) {
        this.qualifiedName = qualifiedName;
    }

    public String getSourceCode() {
        return sourceCode;
    }

    public void setSourceCode(String sourceCode) {
        this.sourceCode = sourceCode;
    }
}

有可能在致电 compilerTask.call(); 不创建类文件?如果是的话怎么做?

Is it possible that after call compilerTask.call(); to not create a class file? If yes how to do that?

推荐答案

对于你的工作,我会使用 JANINO 。仅使用 JavaCompiler 似乎可行,但没有详细记录。请参阅我添加链接问题的注释,以获取与JavaCompiler一起使用的示例。

For what your doing, I would use Janino. It appears doable using just the JavaCompiler, but not well documented. See the comment I added withe linked question for an example of going about it with the JavaCompiler.

编辑:
我发现一个易于理解示例使用 JavaCompiler

这篇关于动态编译而不创建物理文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆