页面上动态编译及执行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. 一 ...
随机推荐
- 【Oracle&SQLServer】并集、交际、补集
1.并集(UNION/UNION ALL) Oracle&SQLServer中用法一致 UNION 去重 UNION ALL 不去重 -- 去重 select * from tablea un ...
- C#之装箱和拆箱
在实际编码过程中,有时候会出现装箱和拆箱操作.下面就类分别认识一下: 需要注意的是,类型转换和这个是不同的.Convert方法并没有发生装箱和拆箱操作,而是类型转换,包括int.parse等等. 装箱 ...
- asp.net 邮件发送类
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- 轮子来袭 vJine.Core Orm 之 02_代码生成
1.下载并安装动软代码生成器: 2.下载vJine.Core.Orm模板: 3.解压模本文件并复制到如下的动软代码生成器模板目录: 4.打开动软代码生成器会看到模板已识别加载: 5.选择模板代码批量生 ...
- OC2_分数类
// // Fraction.h // OC2_分数类 // // Created by zhangxueming on 15/6/10. // Copyright (c) 2015年 zhangxu ...
- (转)传统MySQL+ Memcached架构遇到的问题
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: ...
- props验证
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 07_控制线程_join_线程插队
[join线程简述] join()方法:Thread提供的让一个线程去等待另一个线程完成.当在某个程序执行流中(如main线程)调用其它线程(如t2线程)的join方法(t2.join()),调用线程 ...
- POJ 1661 Help Jimmy -- 动态规划
题目地址:http://poj.org/problem?id=1661 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度 ...
- Json操作
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...