我想重新讨论一个关于类的内存“编译”的旧问题。自从我问过(并且得到一定程度的回答)以来已经过去了大约1/2年,我想重新提出这个问题并看看是否会出现新问题(所以不,我不认为这是重复的)
旧问题可以在这里找到:On-the-fly, in-memory java code compilation for Java 5 and Java 6 - 我建议在回答这个问题之前阅读它(和答案)。
我很满意beanshell正在将一个java类的字符串评估为实际的Class对象。然而,beanshell现在已经在版本2.0b4上站了很久,它的局限性(没有构造函数,甚至没有默认值;没有泛型,没有for-each,没有枚举......)很烦人。
提醒 - 这将用作调试接口,因此性能考虑因素可以忽略不计。但是,我不能让服务器重启,不能将类文件发送到该位置而JSP对我来说是一个非常糟糕的选择(我不会在这里讨论原因)。此外,最终产品必须是Class(或该类的Object),所以我可以传递它。
一些限制:我不能拥有JDK,所以没有javax.tools.JavaCompiler。我没有JSP,因为我没有tomcat或其他“真正的”Web容器。 Java 5语法支持很棒,特别是泛型,枚举和参数化。对默认构造函数的支持非常好。
有什么想法吗?
编辑1:我刚刚发现有一种在beanshell中使用构造函数的循环方式 - 但是你必须声明它们“public void XXX(){...}”而不是通常的方式“public XXX (){...}”。
答案 0 :(得分:2)
如果由于许可原因无法捆绑SUN JDK tools.jar,也许您可以包含Eclipse JDT Core编译器,请参阅
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm
这是例如Jetty Web服务器的JSP实现做了什么。
答案 1 :(得分:0)
难道你不能只是复制到tools.jar并获取javax.tools.JavaCompiler并将其添加到类路径中吗?或者这是许可问题。
这个代码和类路径上的tools.jar似乎有效:
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class Main
{
public static void main(final String[] argv)
throws IOException
{
final File[] files;
final JavaCompiler compiler;
final StandardJavaFileManager fileManager;
final Iterable<? extends JavaFileObject> compilationUnits;
files = new File[]
{
new File(argv[0]),
};
compiler = ToolProvider.getSystemJavaCompiler();
fileManager = compiler.getStandardFileManager(null, null, null);
compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files));
compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
fileManager.close();
}
}
答案 2 :(得分:0)
我记得很久以前读过字节码工程库(BCEL),当时Java 1.4风靡一时。见http://jakarta.apache.org/bcel/index.html。我从来没有使用它,所以我只提到它,因为它看起来接近你所询问的(并且它可以工作,或者至少可以使用较旧的VM)并且我没有看到任何人提及它。
答案 3 :(得分:0)
是否有一个特定原因导致它必须是生成类/对象的 Java 字符串?我的自发反应是JRuby是你正在寻找的东西 - 它似乎是一个非常可靠的平台,而Ruby拥有强大的元编程传统。
答案 4 :(得分:0)
我最终使用了Bean Shell。它并不完美,但它解决了99%的问题。