2009-11-24 41 views
2

我想重温一个关于类的内存“编译”的旧问题。自从我问了一些问题(并且有些回答)以来,大约有1/2年过去了,我想重新提出这个问题,看看是否会有新的东西出现(所以不会,我不认为这是重复的) 。java内存中实时类编译(和加载)

老问题可以在这里找到:On-the-fly, in-memory java code compilation for Java 5 and Java 6 - 我建议在回答这个问题之前阅读它(和答案)。

我非常满意beanshell做一个Java类的字符串到实际的Class对象的繁重工作。然而,beanshell在2.0b4版本上已经有很多年了,它的局限性(没有构造函数,甚至没有默认值;没有泛型,没有for-each,没有枚举...)很烦人。

提醒 - 这是用作调试接口,因此性能考虑可以忽略不计。但是,我无法重新启动服务器,无法将类文件发送到位置,并且JSP对我来说是一个非常糟糕的选择(我不会在这里解释原因)。此外,最终产品必须是一个类(或该类的一个对象),所以我可以传递它。

一些限制:我不能有一个JDK,所以没有javax.tools.JavaCompiler。我没有JSP,因为我没有tomcat或其他“真正的”web容器。 Java 5语法支持将会很棒,尤其是泛型,枚举和参数化。对默认构造函数的支持将会非常好。

任何想法?

编辑1:我刚刚发现有一个在beanshell中有构造函数的循环方法 - 但是你必须声明它们为“public void XXX(){...}”而不是通常的方式“public XXX(){...}”。

回答

0

我结束了使用Bean Shell。这并不完美,但它解决了99%的问题。

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(); 
    } 
} 
+0

号码许可问题。另外,客户端可以更改我的服务器运行的JRE,所以这也是兼容性问题。 – 2009-11-25 09:54:48

2

如果你不能捆绑SUN JDK的tools.jar由于授权方面的原因,也许你可以包括了Eclipse JDT编译内核,而不是见

http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm

这是如Jetty Web服务器的JSP实现的功能。

+0

因为我使用码头,我可能会考虑这一点。好决定。 – 2009-11-25 09:51:02

+0

嗯,我做到了。这需要我:1。直接依靠JDT,这对我来说是一个问题(组织级别),或者依赖于不能保证不会改变的码头内部。无论如何感谢 – 2009-11-26 11:16:53

0

我记得很久以前读过关于字节码工程库(BCEL)的内容,当时Java 1.4已经风靡一时。见http://jakarta.apache.org/bcel/index.html。我从来没有使用它,所以我只提及它,因为它似乎接近你所问的(它工作,或者至少与旧的虚拟机一起工作),我还没有看到任何人提到它。

+0

会考虑它。听起来不像是一个有效的解决方案 - 太多的开销。 – 2009-11-25 09:52:47

0

是否有一个特定的原因为什么它必须是一个Java字符串产生类/对象?我自发的反应是,JRuby就是你正在寻找的东西 - 它似乎是一个非常坚实的平台,Ruby具有元编程的强大传统。

+0

必须是一个Java字符串,因为这是所有开发人员在这里知道的。我想写一个“插件”,它将连接到正在运行的服务器并帮助调试它(生成日志消息,查询内部结构等)。强制每个人学习ruby都会在开始之前将其废弃(没有人会学习 - 没有人会使用它)。 – 2009-11-25 09:54:04

+0

多么悲伤 - 它会像你的手套一样适合你。正如您已经注意到的,Java通常不用于脚本编写是有原因的。我认为Groovy和JavaScript(比Ruby更多的Java-ish)也不可能? – gustafc 2009-11-25 11:18:01

+0

@gustafc:是的,出于同样的原因。 – 2009-11-25 11:26:20