简单java在线测评程序
简单java程序在线测评程序
一.前言
大家过年好!今年的第一篇博客啊!家里没有网,到处蹭无线!日子过得真纠结!因为毕设的需求,简单写了一个java程序在线测评程序,当然也可以在本地测试。
二.思路
首先简单介绍一下思路:
1.得到java程序的源代码,不需要导入包。得到源码之后在前面加入”import java.util.*;”
2.通过JavaCompiler对象可以帮助我们将java源代码编译成class文件。
3.通过DiagnosticCollector对象可以获得编译过程中产生的编译信息。
4.通过StandardJavaFileManager对象管理生成的class文件,例如文件的存放位置。
5.StringSourceJavaObject对象可以对java源码进行包装并处理。
数据是控制台输入的,所以要重定向System.in(注意保存标准的输入流);另外程序的输出是到标准的输出流的,为了获得输出结果,我的方法是重定向输出流到ByteArrayOutputStream,然后利用ByteArrayOutputStream构造BufferedReader。
6.运行程序,通过java的反射机制,获得main函数的Method对象。
7.运行时间的计算: 通过System.currentTimeMillis()方法。
8.程序所需内存: 通过Runtime的freeMemory()方法。
9.异常信息的获取:StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw, true)); sw.toString();
三.问题解决
1. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 出现NullPointerException。
查看部分源码如下:
private static final String[] defaultToolsLocation = { "lib", "tools.jar" }; private Class<?> findSystemToolClass(String toolClassName)throws MalformedURLException, ClassNotFoundException {// try loading class directly, in case tool is on the bootclasspathtry {return Class.forName(toolClassName, false, null);} catch (ClassNotFoundException e) {trace(FINE, e);// if tool not on bootclasspath, look in default tools location (tools.jar)ClassLoader cl = (refToolClassLoader == null ? null : refToolClassLoader.get());if (cl == null) {File file = new File(System.getProperty("java.home"));if (file.getName().equalsIgnoreCase("jre"))file = file.getParentFile();for (String name : defaultToolsLocation)file = new File(file, name);// if tools not found, no point in trying a URLClassLoader// so rethrow the original exception.if (!file.exists())throw e;URL[] urls = { file.toURI().toURL() };trace(FINE, urls[0].toString());cl = URLClassLoader.newInstance(urls);refToolClassLoader = new WeakReference<ClassLoader>(cl);}return Class.forName(toolClassName, false, cl);} }
打印 System.out.println(System.getProperty("java.home")); 如下:
C:\Program Files (x86)\Java\jre6
defaultToolsLocation = { "lib", "tools.jar" }; 也就是最终到
C:\Program Files (x86)\Java\jre6\lib\tools.jar中寻找tools.jar
然而jre6\lib中没有tools.jar, 而是在C:\Program Files (x86)\Java\jdk\lib中。最直接的办法就是将它复制进去就行了。
2.异常信息的获取。
3.输入流和输出流的重定向。
详细内容请看代码!
四.代码
![](/assets/blank.gif)
![](/assets/blank.gif)
import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import java.net.URI; import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern;import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider;public class CompileAndRunJavaFile {public static void main(String[] args) {StringBuilder code = new StringBuilder();try {BufferedReader br = new BufferedReader(new FileReader(new File("测试程序地址")));String content;while((content = br.readLine()) != null){code.append(content).append("\n");}} catch (Exception e) {e.printStackTrace();}CompileAndRunJavaFile cr = new CompileAndRunJavaFile();cr.compileAndRunJavaFile(code.toString());if(cr.isCompileAndRunOK()) {System.out.println("运行时间: " + cr.getUseTime() + "ms");System.out.println("内存使用: " + cr.getUseMemory() + "kb9");System.out.println("运行结果: \n" + cr.getOutMsg());} else if(cr.isCompilerError()) {System.out.println("编译错误: " + cr.getCE());} else if(cr.isRunningError()) {System.out.println("运行错误: " + cr.getError());}}//编译错误private StringBuilder ce = new StringBuilder();public String getCE(){return ce.toString();}//内存使用private double useMemory = 0.0;public double getUseMemory(){return useMemory;}//运行时间private long useTime = 0;public long getUseTime(){return useTime;}//输出信息private StringBuilder outMsg = new StringBuilder();public String getOutMsg(){return outMsg.toString();}//异常信息private String error = null;public String getError(){return error;}//是否正常编译并运行private boolean isCompileAndRunOK = false; public boolean isCompileAndRunOK(){return isCompileAndRunOK;}//程序的运行时间, 单位:msprivate int limitTime = 2000;//程序所占内存, 单位 :KBprivate double limitMemory = 256000.0;public void setLimitTime(int limitTime){this.limitTime = limitTime;}public void setLimitMemory(double limitMemory){this.limitMemory = limitMemory;}//是否为编译错误private boolean isCompilerError = false;public boolean isCompilerError(){return isCompilerError;}//是否为运行错误private boolean isRunningError = false;public boolean isRunningError(){return isRunningError;}private static final String className = "Main";private static final String methodName = "main";private String getClassOutput(){//设置class文件的存放位置if(System.getProperty("java.class.path").contains("bin")) return "bin/";else return "./";}private void compileAndRunJavaFile(String code){PrintStream ps = null;FileInputStream fis = null;BufferedReader br = null;//保存标准输出流InputStream stdIn = System.in;//保存标准输入流PrintStream stdOut = System.out;//为源代码导入默认的包code = "import java.util.*;\n" + code;try {JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();// define the diagnostic object, which will be used to save the// diagnostic informationDiagnosticCollector<JavaFileObject> oDiagnosticCollector = new DiagnosticCollector<JavaFileObject>();StandardJavaFileManager fileManager = compiler.getStandardFileManager(oDiagnosticCollector, null, null);// set class output locationfileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File[] { new File(getClassOutput()) }));StringSourceJavaObject sourceObject = new CompileAndRunJavaFile.StringSourceJavaObject(className, code);Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);CompilationTask task = compiler.getTask(null, fileManager, oDiagnosticCollector, null, null, fileObjects);boolean result = task.call();if (result) {Runtime runtime = Runtime.getRuntime();Class<?> clazz = Class.forName(className);Method method = clazz.getMethod(methodName, new Class<?>[]{String[].class});//重置输入流, 需要存放数据文件的文件名fis = new FileInputStream(new File("数据文件地址"));System.setIn(fis);//重置输出流,需要获得控制台的输出ByteArrayOutputStream bao = new ByteArrayOutputStream();ps = new PrintStream(bao);System.setOut(ps);long startFreeMemory = runtime.freeMemory();//Java 虚拟机中的空闲内存量//执行时间也是无法知道,因为dos执行java命令,程序无法知道它到底执行到那里了,两个进程,互不了解long startCurrentTime = System.currentTimeMillis();//获取系统当前时间method.invoke(null, new Object[]{null});long endCurrentTime = System.currentTimeMillis();long endFreeMemory = runtime.freeMemory();//内存的使用情况,不是很精确useMemory = (startFreeMemory-endFreeMemory)/1024.0;if(useMemory > limitMemory) throw new Exception("Out Limit Memory!");useTime = endCurrentTime-startCurrentTime;if(useTime > limitTime) throw new Exception("Time Limited!");//获得控制台的输出br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bao.toByteArray())));String outc = null;while((outc = br.readLine()) != null)outMsg.append(outc).append("\n");//正常编译并运行isCompileAndRunOK = true;} else {isCompilerError = true;//打印编译的错误信息Pattern p = Pattern.compile("Main.java\\D*(\\d+):", Pattern.DOTALL);for (Diagnostic<? extends JavaFileObject> oDiagnostic : oDiagnosticCollector.getDiagnostics()){/*信息示例:Compiler Error: Main.java:8: 找不到符号符号: 类 Scanner位置: 类 Main*///将行号减1Matcher m = p.matcher("Compiler Error: " + oDiagnostic.getMessage(null));if(m.find()) {ce.append(m.replaceAll("Main.java " + String.valueOf(Integer.valueOf(m.group(1))-1)) + ":").append("\n");} else {ce.append("Compiler Error: " + oDiagnostic.getMessage(null)).append("\n");}}}} catch (Exception e) {isRunningError = true;StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw, true));Pattern p = Pattern.compile("Main.java\\D*(\\d+)", Pattern.DOTALL);Matcher m = p.matcher(sw.toString());if(m.find()){error = m.replaceAll("Main.java " + String.valueOf(Integer.valueOf(m.group(1))-1) + ":");} else {error = sw.toString();}} finally {//关闭流try {if(fis != null)fis.close();if(ps != null)ps.close(); if(br != null)br.close();} catch (IOException e) {e.printStackTrace();}//恢复输入输出流 System.setIn(stdIn);System.setOut(stdOut);}}private class StringSourceJavaObject extends SimpleJavaFileObject {private String content = null;public StringSourceJavaObject(String name, String content) {super(URI.create(name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);this.content = content;}public CharSequence getCharContent(boolean ignoreEncodingErrors) {return content;}} }
View Code
五.运行结果显示
1.正常运行
运行时间: 16ms
内存使用: 225.5546875kb
运行结果:
5 4 3 2 1
2.编译错误
编译错误: Compiler Error: Main.java 8 找不到符号
符号: 类 Scanner
位置: 类 Main:
Compiler Error: Main.java 8 找不到符号
符号: 类 Scanner
位置: 类 Main:
3.运行错误
(1)运行错误: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.test.CompileAndRunJavaFile.compileAndRunJavaFile(CompileAndRunJavaFile.java:163)
at com.test.CompileAndRunJavaFile.main(CompileAndRunJavaFile.java:44)
Caused by: java.lang.StackOverflowError
at Main.fun(Main.java 4:)
at Main.fun(Main.java 4:)
(2)运行错误: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.test.CompileAndRunJavaFile.compileAndRunJavaFile(CompileAndRunJavaFile.java:163)
at com.test.CompileAndRunJavaFile.main(CompileAndRunJavaFile.java:44)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 6
at Main.main(Main.java 18:)
... 6 more
六.测试程序
![](/assets/blank.gif)
![](/assets/blank.gif)
public class Main {public static void fun(){fun();}public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int[] array = new int[n];for(int i=0; i<n; ++i)array[i] = scan.nextInt();for(int i=0; i<n; ++i)System.out.print(array[i] + " ");System.out.println();//array[n+1] = 0;//fun(); }}
View Code
转载于:https://www.cnblogs.com/hujunzheng/p/5203067.html
简单java在线测评程序相关推荐
- java 在线测评_简单java在线测评程序
简单java程序在线测评程序 v一.前言 大家过年好!今年的第一篇博客啊!家里没有网,到处蹭无线!日子过得真纠结!因为毕设的需求,简单写了一个java程序在线测评程序,当然也可以在本地测试. v二.思 ...
- 亚信java在线测评题库_校招秋招,网申在线测评如何训练才能通过?
校招又分为春招秋招,是无数毕业生就业的重要通道,尤其是今年的情况使得在线测评变得更加普及,将来这也是必然的趋势.校招中第一道门槛便是这线上测评.用人单位在收到毕业生的简历后,先发送线上测评,通过线上测 ...
- java在线测评系统_JavaWeb项目:在线评测系统
此项目为本人的Java大作业. 一.项目概况 1.1设计内容 一个在线评测系统,分用户和管理员两种身份.用户能够通过注册登录,参加比赛,最后实时得到比赛结果,并保存历史比赛结果:管理员除此之外还能录入 ...
- java程序计时器_求完整简单java计时器小程序代码,急!!
放肆丶小侽人 回答时间:2019-12-05 向TA提问 import java.awt.Button; import java.awt.Color; import java.awt.FlowLayo ...
- 简单java socket_基于Java Socket实现一个简易在线聊天功能(一)
最近做了一个项目,其中有一个在线网页交流的需求,好久没写代码了,手都生疏了,于是先写demo练练手,分享到脚本之家平台,以此做个记录,方便自己和大家使用. 先给大家说下实现步骤分这样几大步: 1.使用 ...
- java udp简单聊天程序_Java基于UDP协议实现简单的聊天室程序
最近比较闲,一直在抽空回顾一些java方面的技术应用. 今天没什么事做,基于udp协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对java网络编程方面的一个简单回忆. ...
- 在线测试c语言程序代码,C语言在线测评系统的使用
系统学习请关注公众号:C简简 一.在线测评系统 Online Judge系统(简称OJ)是一个在线的判题系统.用户可以在线提交程序源代码,系统对源代码进行编译和执行,并通过预先设计的测试数据来检验程序 ...
- java udp 聊天室_Java基于UDP协议实现简单的聊天室程序
最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆. ...
- java毕业设计在线测评系统2021Mybatis+系统+数据库+调试部署
java毕业设计在线测评系统2021Mybatis+系统+数据库+调试部署 java毕业设计在线测评系统2021Mybatis+系统+数据库+调试部署 本源码技术栈: 项目架构:B/S架构 开发语言: ...
最新文章
- Runtime-消息发送和消息转发
- 当ABAP遇到OLE
- win10任务管理器快捷键_你都知道吗?Win10任务管理器到底藏了多少秘密
- 【小技巧积累】设置ListView控件的Item不在Tab键导航序列中
- Hibernate懒加载
- TI CC2480 -- Z-Accel介绍
- 图的表示方法和C++实现
- CV算法助理 | 华为外包招聘
- linux怎么判断全局符号,Linux下全局符号覆盖有关问题
- java 线程安全 计数_java – 实现线程安全共享计数器的功能方法
- java 环境变量_Win10系统配置Java环境变量
- 190421每日一句
- linux命令行添加管理员用户,Linux基础命令---添加用户useradd
- Python安装教程(新手)
- 南京大学计算机考研复试名单,2017南京大学计算机科学与技术系考研复试名单...
- 游戏是怎么赚钱的 - 科普篇
- Mac屏幕截图快捷键
- 【DSGN 解读】用于三维目标检测的深度立体几何网络
- 金彩教育:如何提升店铺的信誉
- iOS应用的游戏中心和排行榜
热门文章
- dynamo python修改多个参数_40岁小白学了30天python发现,编程真的其乐无穷
- tomcat启动成功 未加载项目_喜讯!济宁医学院附属医院SPD项目成功启动
- 判断是否包含大写字符_Python最常用的数据类型中字符串基础函数使用知识点讲解...
- uniapp 仿钉钉考勤统计页面的日历组件,通过日历展示每日考勤打卡情况,支持在日历上打两种不同类型的点,大致适配各种分辨率
- el-table中奇偶行背景色显示不同的颜色
- SpringBoot2 整合 XFIRE 服务端和客户端
- JavaScript-字符串
- html-表单的应用
- curl查看swift状态命令_前端应该会的23个linux常用命令
- pythonxml库_对python 生成拼接xml报文的示例详解