页面上动态编译及执行java代码
2015-07-15 23:08
861 查看
本文地址:http://www.cnblogs.com/liaoyu/p/real-time-compile-and-run-java-code-web-app.html
最近看到同事在页面上编译和执行java代码,有点像Web IDE,感觉很酷就试着自己实现下。
预期要实现以下几个功能:
页面上使用textarea作为简单的代码编辑器,通过单击执行按钮向服务器发送请求
服务器端接收到java代码,进行简单的校验,若检验通过则进行编译
如果编译错误,返回异常信息
重定向代码中的system.out输出,将结果返回到客户端
编译时需指定生成的.class文件的路径,由于是在tomcat作为服务器,存在到WEB-INF\classes下即可:
在使用反射执行该类时,需将System.out的输出重定向到ByteArrayOutputStream,最后将该结果返回到客户端
我在页面中是使用angularjs来实现交互,发现angularjs无法通过在
![](https://images0.cnblogs.com/blog2015/477737/201507/152303585323067.jpg)
查看完整源代码:点击这里
最近看到同事在页面上编译和执行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 才有效。运行效果
![](https://images0.cnblogs.com/blog2015/477737/201507/152303585323067.jpg)
查看完整源代码:点击这里
相关文章推荐
- java的测试
- 简单的ftp服务器实现 (java)
- 13.Java5条件阻塞Condition的应用
- java的myeclipse,java页面修改默认的javadoc方法
- Eclipse中设置ButterKnife进行注解式开发步骤
- java基础第四天
- java通过选择年月生成天下拉框
- 深入浅出的理解框架(Struts2、Hibernate、Spring)与 MVC 设计模式
- Eclipse搜索
- java之动态代理
- Java语言基础1--专题课 递归
- java io 装饰设计模式
- JDK 源码 阅读 - 2 - 设计模式 - 创建型模式
- java 数据类型转换
- Eclipse Ndk开发中的Method 'NewStringUTF' could not be resolved问题
- Java基础Map的使用
- Java语言基础1--综合案例(数字加密问题):
- java学习&复习 2015/07/15
- java web系统调优方案
- Java基本语法--变量与常量