有没有一种运行Java程序来编译Java源代码(以字符串形式传递)的方法?从字符串编译Java源代码?
Class newClass = Compiler.compile ("class ABC { void xyz {etc. etc. } }");
理想情况下,传入的源代码所引用的任何类都将被程序的类加载器解析。
是否有这样的事情存在?
有没有一种运行Java程序来编译Java源代码(以字符串形式传递)的方法?从字符串编译Java源代码?
Class newClass = Compiler.compile ("class ABC { void xyz {etc. etc. } }");
理想情况下,传入的源代码所引用的任何类都将被程序的类加载器解析。
是否有这样的事情存在?
当然。查看JavaCompiler
类和javax.tools
包中的其他类。
自Java 1.6以来,它们一直存在。
(正如在评论中指出的@Sergey Tachenov,它需要JDK安装为必要的tools.jar文件带有JDK而不是JRE)
取决于你想做。 如果你只是想运行一些代码,你可以使用BeanShell。这不是一个Java编译类,但是非常有用,使灵活的东西
你可以尝试我的本质jcf库这样做。在调试中运行时,可以将源代码写入文件,以便您可以进入代码。否则,它会在内存中执行所有操作。它将JavaCompiler包装在tools.jar中
它接受一个字符串,编译并将其加载到当前类加载器中并返回该类。它处理嵌套/内部类。
http://vanillajava.blogspot.com/2010/11/more-uses-for-dynamic-code-in-java.html
注:我还没有在OSGi的这个工作。 ;)
Javassist可以在运行时从源代码的字符串生成和加载类和方法。 如果需要,也可以在文件系统中转储生成的类。
当前,您可以在这些字符串中传递的代码存在较小的限制,例如,它不能包含泛型,枚举或自动装箱和收件箱原语。 点击此处了解详情:
你需要的是一个扩展JavaFileObject中
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
public class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
public 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;
}
}
这可以如下的一类:
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
if(jc == null) throw new Exception("Compiler unavailable");
String code = "public class CustomProcessor { /*custom stuff*/ }";
JavaSourceFromString jsfs = new JavaSourceFromString("CustomProcessor", code);
Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(jsfs);
List<String> options = new ArrayList<String>();
options.add("-d");
options.add(compilationPath);
options.add("-classpath");
URLClassLoader urlClassLoader = (URLClassLoader)Thread.currentThread().getContextClassLoader();
StringBuilder sb = new StringBuilder();
for (URL url : urlClassLoader.getURLs()) {
sb.append(url.getFile()).append(File.pathSeparator);
}
sb.append(compilationPath);
options.add(sb.toString());
StringWriter output = new StringWriter();
boolean success = jc.getTask(output, null, null, options, null, fileObjects).call();
if(success) {
logger.info(LOG_PREFIX + "Class has been successfully compiled");
} else {
throw new Exception("Compilation failed :" + output);
}
你在哪里声明了'compilationPath'变量? – bachr 2014-01-21 09:48:23
它在代码中更高,只是一个字符串 – MonoThreaded 2014-01-24 14:36:25
我发现这个例子中,这正是我需要的。 http://www.ibm.com/developerworks/java/library/j-jcomp/index.html – user566822 2012-10-24 23:48:18