页面上动态编译及执行java代码
本文地址:http://www.cnblogs.com/liaoyu/p/real-time-compile-and-run-java-code-web-app.html
最近看到同事在页面上编译和执行java代码,有点像Web IDE,感觉很酷就试着自己实现下。
预期要实现以下几个功能:
- 页面上使用textarea作为简单的代码编辑器,通过单击执行按钮向服务器发送请求
- 服务器端接收到java代码,进行简单的校验,若检验通过则进行编译
- 如果编译错误,返回异常信息
- 重定向代码中的system.out输出,将结果返回到客户端
相关实现
public class RuntimeCompiler {
private List<String> options = null;
private JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
private DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
private StringBuffer traceMsg = new StringBuffer();
public RuntimeCompiler(String... options) {
// inital compile params
if (options != null && options.length > 0) {
this.options = Arrays.asList(options);
}
}
public boolean compile(String className, String code) {
JavaFileObject sourceFile = new StringJavaFileObject(className, code);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(sourceFile);
CompilationTask task = compiler.getTask(null, null, diagnostics, options, null, compilationUnits);
boolean result = task.call();
// Record compile error messages
for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) {
traceMsg.append(diagnostic.getMessage(null)).append("\n");
traceMsg.append(String.format("Error on line %d in %s%n", diagnostic.getLineNumber(),
((FileObject) diagnostic.getSource()).toUri()));
}
return result;
}
public String getTraceMsg() {
return traceMsg.toString();
}
}
编译时需指定生成的.class文件的路径,由于是在tomcat作为服务器,存在到WEB-INF\classes下即可:
String realPath = request.getServletContext().getRealPath("/") + "WEB-INF\\classes";
RuntimeCompiler rc = new RuntimeCompiler("-d", realPath);
boolean success = rc.compile(className, code);
在使用反射执行该类时,需将System.out的输出重定向到ByteArrayOutputStream,最后将该结果返回到客户端
// Create a stream to hold the output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(baos);
// Tell Java to use your special stream
System.setOut(printStream);
if (success) {
try {
Class.forName(fullClassName).getDeclaredMethod("main", new Class[] {
String[].class
}).invoke(null, new Object[] {
null
});
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException e) {
result = "Load class error: " + e;
}
}
// flush output stream
System.out.flush();
out.print(baos.toString());
我在页面中是使用angularjs来实现交互,发现angularjs无法通过在 textarea 标签里边来设置默认值,只好用指令 ng-model 绑定变量,在controller中设置初始值。
目前存在的问题
当在页面上的修改同一个类时,连续点击run,会有10秒左右的延迟,这是由于它会编译成内容不同的.class文件,只有当 org.apache.catalina.core.StandardContext reload 才有效。
运行效果

查看完整源代码:点击这里
页面上动态编译及执行java代码的更多相关文章
- AJPFX编写cmd界面下一键编译、执行java代码的bat脚本
此脚本适合刚接触java的同学,在cmd界面下用jc取代 复杂的 javac *.java + java main使用说明:把脚本内容复制到txt文本中,修改后缀名为.bat,运行一次即可完成配置, ...
- jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行?
jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行? 因为在解析时最新解析的就是JA ...
- 在命令符模式下编译并执行Java程序
对于Java初学者,建议使用纯文本文件来编写Java程序,并在命令符模式下使用工具程序编译和执行Java程序.使用javac工具编译.java,使用java工具执行.class.(推荐sublime编 ...
- 如何用javac 和java 编译运行整个Java工程 (转载)【转】在Linux下编译与执行Java程序
如何用javac 和java 编译运行整个Java工程 (转载) http://blog.csdn.net/huagong_adu/article/details/6929817 [转]在Linux ...
- 用可配置外部工具的编辑器编译与执行java
用可配置外部工具的编辑器编译与执行java 最近用了everedit.觉得比之前平时用的Editplus有更多的细节与功能要好许多. 这里就写写用everedit编译与执行java的方法. 原理 ja ...
- Windows和Linux执行Java代码的不同方式
一.Windows 下编译并执行 Java 字节码文件(类文件) 1.编译 Hello.java 源码文件: java -d . Hello.java 2.执行 Hello.class 字节码文件: ...
- 在执行java代码时,设置了断点,然后莫名的没执行完方法内的代码就结束了,此刻一般在出错处代码用try,catch包括起来
在执行java代码时,设置了断点,然后莫名的没执行完方法内的代码就结束了,此刻一般在出错处代码用try,catch包括起来就能看到是什么异常了,记住try,catch语句的作用
- C#动态编译、执行代码
在开始之前,先熟悉几个类及部分属性.方法:CSharpCodeProvider.ICodeCompiler.CompilerParameters.CompilerResults.Assembly. 一 ...
- 如何用C#动态编译、执行代码
在开始之前,先熟悉几个类及部分属性.方法:CSharpCodeProvider.ICodeCompiler.CompilerParameters.CompilerResults.Assembly. 一 ...
随机推荐
- zabbix数据存储
一.zabbix数据库 zabbix-server将采集到的数据存储在数据库中,最常用的Mysql,数据存储的大小和每秒处理的数据量有关,数据存储取决于每秒处理的数据量和Housekeeper的删除数 ...
- oc 通过webView调用js方法
- (void)viewDidLoad { [super viewDidLoad]; //加载本地web页面 web = [[UIWebView alloc]init]; web.background ...
- Java添加事件的四种方式
Java添加事件的几种方式(转载了codebrother的文章,做了稍微的改动) /** * Java事件监听处理——自身类实现ActionListener接口,作为事件监听器 * * @author ...
- RX编程笔记——JavaScript 获取地理位置
RX编程笔记——JavaScript 获取地理位置 2016-07-05
- 懒加载 lazy load
懒加载(Load On Demand)是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据, 而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用. 比 ...
- PERL代码摘录
1. 语法与数据结构 #嵌套哈希的赋值和取值 $HashTable{$key} = [@Array] #这个是赋值 @Array = @{ $HashTable{$key} } # 这个是取值 #Pe ...
- 八,WPF 命令
WPF命令模型 ICommand接口 WPF命令模型的核心是System.Windows.Input.ICommand接口,该接口定义了命令的工作原理,它包含了两个方法和一个事件: public in ...
- hdu 1427 dfs
速算24点 题意:随机给你四张牌,包括 A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用'+','-','*','/'运算符以及括号改变运算 顺序,使得最终 ...
- hadoop基本命令1
(大讲台——国内首个it在线混合式自适应学习平台,轻量级的高薪就业和技能提升解决方案) 1.列出所有Hadoop Shell支持的命令$ bin/hadoop fs -help2.显示关于某个命令的详 ...
- hadoop完全分布式安装(转)
1 安装Vmware WorkStation软件 有些人会问,为何要安装这个软件,这是一个VM公司提供的虚拟机工作平台,后面需要在这个平台上安装linux操作系统.具体安装过程网上有很多资料,这里不作 ...