gpt4 book ai didi

java - 如何使用 eclipse 编译器进行独立的即时内存编译?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:25:45 24 4
gpt4 key购买 nike

与 JDK 中包含的编译器及其 API 相比,eclipse 编译器及其 API 具有一些显着优势(对我的应用程序特别有益),因此我想使用它。我有一个独立的实用程序,我想尽量减少它的大小和依赖性。

访问 eclipse 编译器(最少 jar 文件集及其下载位置)并在内存中即时编译生成的代码的方法是什么?

最佳答案

通过 starting from this page 下载 ECJ ,单击最新版本,然后找到并下载文件 ecj-[版本].jar。为此,我使用 4.2.1。在您的类路径中引用此 jar。

您使用org.eclipse.jdt.internal.compiler.Compiler。构造函数的大多数东西都有可用的默认值。您只需以 ICompilerRequestor 的形式给它一个结果回调。下面的示例使用一个简单的字节类加载器来测试结果。要进行级联编译,您需要创建 FileSystem 的子类,覆盖 INameEnvironment 中的方法。

package test.eclipse.compiler;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.util.Util;


public class TestCompile {
static class ByteClassLoader extends ClassLoader {
private Map<String, byte[]> classMap;


public ByteClassLoader(Map<String, byte[]> classMap) {
super();
this.classMap = classMap;
}

protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = classMap.get(name);
if (bytes == null) {
return super.findClass(name);
} else {
return defineClass(name, bytes, 0, bytes.length);
}
}
}


public static void compile(String code, String filename) {
ArrayList<Classpath> cp = new ArrayList<FileSystem.Classpath>();
Util.collectRunningVMBootclasspath(cp);
INameEnvironment env = new NameEnv(cp.toArray(new FileSystem.Classpath[cp.size()]), null);
ICompilerRequestor requestor = new ICompilerRequestor() {
@Override
public void acceptResult(CompilationResult result) {
ClassFile[] cf = result.getClassFiles();
HashMap<String, byte[]> classMap = new HashMap<String, byte[]>();
classMap.put("Test", cf[0].getBytes());
ByteClassLoader cl = new ByteClassLoader(classMap);
try {
Class<?> c = cl.loadClass("Test");
Method m = c.getMethod("test");
m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}
};
Compiler compiler = new Compiler(env, DefaultErrorHandlingPolicies.exitAfterAllProblems(),
new CompilerOptions(), requestor, new DefaultProblemFactory());

ICompilationUnit[] units = new ICompilationUnit[] { new CompilationUnit(code.toCharArray(), filename, null) };
compiler.compile(units);
}

public static void main(String[] args) {
compile("public class Test { public static void test() { System.out.println(\"Hello, world.\"); }}",
"Test.java");
}
}

this blog post 许可复制

关于java - 如何使用 eclipse 编译器进行独立的即时内存编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14226357/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com