├── bin └── cn │ └── superman │ └── sandbox │ ├── callable │ ├── ProblemCallable$1.class │ ├── ProblemCallable$2.class │ ├── ProblemCallable$3.class │ ├── ProblemCallable.class │ └── ProblemItemCallable.class │ ├── constant │ ├── CommunicationSignal$RequestSignal.class │ ├── CommunicationSignal$ResponseSignal.class │ ├── CommunicationSignal.class │ └── ConstantParameter.class │ ├── core │ ├── Sandbox$1$1.class │ ├── Sandbox$1.class │ ├── Sandbox$2$1.class │ ├── Sandbox$2.class │ ├── Sandbox$3.class │ ├── Sandbox.class │ ├── classLoader │ │ └── SandboxClassLoader.class │ ├── securityManager │ │ └── SandboxSecurityManager.class │ ├── systemInStream │ │ └── ThreadInputStream.class │ └── systemOutStream │ │ ├── CacheOutputStream$1.class │ │ └── CacheOutputStream.class │ └── dto │ ├── Problem.class │ ├── ProblemResult.class │ ├── ProblemResultItem.class │ ├── Request.class │ ├── Response.class │ ├── SandBoxStatus.class │ └── SandboxInitData.class ├── gson-2.6.2.jar ├── lib └── gson-2.6.2.jar └── src └── cn └── superman └── sandbox ├── callable ├── ProblemCallable.java └── ProblemItemCallable.java ├── constant ├── CommunicationSignal.java └── ConstantParameter.java ├── core ├── Sandbox.java ├── classLoader │ └── SandboxClassLoader.java ├── securityManager │ └── SandboxSecurityManager.java ├── systemInStream │ └── ThreadInputStream.java └── systemOutStream │ └── CacheOutputStream.java └── dto ├── Problem.java ├── ProblemResult.java ├── ProblemResultItem.java ├── Request.java ├── Response.java ├── SandBoxStatus.java └── SandboxInitData.java /bin/cn/superman/sandbox/callable/ProblemCallable$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/callable/ProblemCallable$1.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/callable/ProblemCallable$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/callable/ProblemCallable$2.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/callable/ProblemCallable$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/callable/ProblemCallable$3.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/callable/ProblemCallable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/callable/ProblemCallable.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/callable/ProblemItemCallable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/callable/ProblemItemCallable.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/constant/CommunicationSignal$RequestSignal.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/constant/CommunicationSignal$RequestSignal.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/constant/CommunicationSignal$ResponseSignal.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/constant/CommunicationSignal$ResponseSignal.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/constant/CommunicationSignal.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/constant/CommunicationSignal.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/constant/ConstantParameter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/constant/ConstantParameter.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/Sandbox$1$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/Sandbox$1$1.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/Sandbox$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/Sandbox$1.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/Sandbox$2$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/Sandbox$2$1.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/Sandbox$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/Sandbox$2.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/Sandbox$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/Sandbox$3.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/Sandbox.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/Sandbox.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/classLoader/SandboxClassLoader.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/classLoader/SandboxClassLoader.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/securityManager/SandboxSecurityManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/securityManager/SandboxSecurityManager.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/systemInStream/ThreadInputStream.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/systemInStream/ThreadInputStream.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/systemOutStream/CacheOutputStream$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/systemOutStream/CacheOutputStream$1.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/core/systemOutStream/CacheOutputStream.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/core/systemOutStream/CacheOutputStream.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/Problem.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/Problem.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/ProblemResult.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/ProblemResult.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/ProblemResultItem.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/ProblemResultItem.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/Request.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/Request.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/Response.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/Response.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/SandBoxStatus.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/SandBoxStatus.class -------------------------------------------------------------------------------- /bin/cn/superman/sandbox/dto/SandboxInitData.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/bin/cn/superman/sandbox/dto/SandboxInitData.class -------------------------------------------------------------------------------- /gson-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/gson-2.6.2.jar -------------------------------------------------------------------------------- /lib/gson-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superman544/JavaOJSandbox/8fef9b0fee7a2f88782f86b1ee44ea11b4237be3/lib/gson-2.6.2.jar -------------------------------------------------------------------------------- /src/cn/superman/sandbox/callable/ProblemCallable.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.callable; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.concurrent.Callable; 8 | import java.util.concurrent.CancellationException; 9 | import java.util.concurrent.CountDownLatch; 10 | import java.util.concurrent.ExecutorService; 11 | import java.util.concurrent.Executors; 12 | import java.util.concurrent.Future; 13 | import java.util.concurrent.FutureTask; 14 | import java.util.concurrent.ThreadFactory; 15 | import java.util.concurrent.TimeUnit; 16 | import java.util.concurrent.TimeoutException; 17 | 18 | import cn.superman.sandbox.core.systemInStream.ThreadInputStream; 19 | import cn.superman.sandbox.core.systemOutStream.CacheOutputStream; 20 | import cn.superman.sandbox.dto.Problem; 21 | import cn.superman.sandbox.dto.ProblemResultItem; 22 | 23 | public class ProblemCallable implements Callable> { 24 | private Method mainMethod; 25 | private Problem problem; 26 | private CacheOutputStream resultBuffer; 27 | private Runtime run = null; 28 | private CountDownLatch countDownLatch = null; 29 | private ThreadInputStream threadSystemIn; 30 | private static final ExecutorService itemGetThreadPool = Executors 31 | .newCachedThreadPool(new ThreadFactory() { 32 | @Override 33 | public Thread newThread(Runnable r) { 34 | Thread thread = new Thread(r); 35 | thread.setName("itemGetThreadPool id " 36 | + System.currentTimeMillis()); 37 | return thread; 38 | } 39 | }); 40 | private static final ExecutorService itemExecThreadPool = Executors 41 | .newCachedThreadPool(new ThreadFactory() { 42 | @Override 43 | public Thread newThread(Runnable r) { 44 | Thread thread = new Thread(r); 45 | thread.setName("itemExecThreadPool id " 46 | + System.currentTimeMillis()); 47 | return thread; 48 | } 49 | }); 50 | 51 | public ProblemCallable(Method mainMethod, Problem problem, 52 | CacheOutputStream resultBuffer, ThreadInputStream threadSystemIn) { 53 | this.mainMethod = mainMethod; 54 | this.problem = problem; 55 | this.resultBuffer = resultBuffer; 56 | this.threadSystemIn = threadSystemIn; 57 | run = Runtime.getRuntime(); 58 | } 59 | 60 | @Override 61 | public List call() throws Exception { 62 | List paths = problem.getInputDataFilePathList(); 63 | final List resultItems = new ArrayList(); 64 | countDownLatch = new CountDownLatch(paths.size()); 65 | // 为了内存使用比较准确,先大概的执行一次回收吧 66 | run.gc(); 67 | 68 | for (int i = 0; i < paths.size(); i++) { 69 | final String path = paths.get(i); 70 | itemExecThreadPool.execute(new Runnable() { 71 | @Override 72 | public void run() { 73 | resultItems.add(process(path)); 74 | } 75 | }); 76 | } 77 | 78 | // 阻塞线程,等待所有结果都计算完了,再返回 79 | countDownLatch.await(); 80 | return resultItems; 81 | } 82 | 83 | private ProblemResultItem process(String inputFilePath) { 84 | ProblemResultItem item = null; 85 | ProblemItemCallable itemCallable = null; 86 | long beginMemory = 0; 87 | long beginTime = 0; 88 | long endTime = 0; 89 | long endMemory = 0; 90 | Future submit = null; 91 | 92 | try { 93 | itemCallable = new ProblemItemCallable(mainMethod, inputFilePath, 94 | resultBuffer, threadSystemIn); 95 | 96 | submit = itemGetThreadPool.submit(itemCallable); 97 | beginMemory = run.totalMemory() - run.freeMemory(); 98 | beginTime = System.nanoTime(); 99 | 100 | item = submit 101 | .get(problem.getTimeLimit() + 2, TimeUnit.MILLISECONDS); 102 | 103 | if (item == null) { 104 | killThread((FutureTask) submit); 105 | throw new TimeoutException(); 106 | } 107 | 108 | endTime = System.nanoTime(); 109 | endMemory = run.totalMemory() - run.freeMemory(); 110 | } catch (Exception e) { 111 | // 出现了意外,先关闭资源再说(如已经打开的流等) 112 | itemCallable.colseResource(); 113 | killThread((FutureTask) submit); 114 | item = new ProblemResultItem(); 115 | item.setNormal(false); 116 | if (e instanceof CancellationException 117 | || e instanceof TimeoutException) { 118 | // 超时了,会进来这里 119 | item.setMessage("超时"); 120 | } else { 121 | item.setMessage(e.getMessage()); 122 | } 123 | endTime = System.nanoTime(); 124 | endMemory = run.totalMemory() - run.freeMemory(); 125 | } 126 | // 时间为毫微秒,要先转变为微秒再变为毫秒 127 | item.setUseTime((endTime - beginTime) / 1000 / 1000); 128 | item.setUseMemory(endMemory - beginMemory); 129 | item.setInputFilePath(inputFilePath); 130 | if (item.getUseMemory() > problem.getMemoryLimit()) { 131 | item.setNormal(false); 132 | item.setMessage("超出内存限制"); 133 | } 134 | // 无论怎么样,这里必须最后都要进行减一,不然将会一直阻塞线程,最终无法返回结果 135 | countDownLatch.countDown(); 136 | return item; 137 | } 138 | 139 | /** 140 | * 需要注意的是,这里将会调用线程stop方法,因为只有这样才能强行终止超时的线程,而又因为这里并不需要保证什么原子性以及一致性的业务要求, 141 | * 所以用stop方法是没什么大问题的 142 | * 143 | * @param submit 144 | * @throws NoSuchFieldException 145 | * @throws SecurityException 146 | * @throws IllegalArgumentException 147 | * @throws IllegalAccessException 148 | */ 149 | @SuppressWarnings("deprecation") 150 | private void killThread(FutureTask submit) { 151 | try { 152 | submit.cancel(true); 153 | // 利用反射,强行取出正在运行该任务的线程 154 | Field runner = submit.getClass().getDeclaredField("runner"); 155 | runner.setAccessible(true); 156 | Thread execThread = (Thread) runner.get(submit); 157 | execThread.stop(); 158 | submit.cancel(true); 159 | } catch (Exception e) { 160 | System.err.println(e); 161 | } 162 | 163 | } 164 | 165 | public Problem getProblem() { 166 | return problem; 167 | } 168 | 169 | public void setProblem(Problem problem) { 170 | this.problem = problem; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/callable/ProblemItemCallable.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.callable; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.util.concurrent.Callable; 9 | 10 | import cn.superman.sandbox.core.systemInStream.ThreadInputStream; 11 | import cn.superman.sandbox.core.systemOutStream.CacheOutputStream; 12 | import cn.superman.sandbox.dto.ProblemResultItem; 13 | 14 | public class ProblemItemCallable implements Callable { 15 | private Method mainMethod; 16 | private CacheOutputStream resultBuffer; 17 | private FileInputStream fileInputStream; 18 | private ThreadInputStream threadSystemIn; 19 | 20 | public ProblemItemCallable(Method mainMethod, String inputFilePath, 21 | CacheOutputStream resultBuffer, ThreadInputStream threadSystemIn) { 22 | this.mainMethod = mainMethod; 23 | this.resultBuffer = resultBuffer; 24 | this.threadSystemIn = threadSystemIn; 25 | // 重定向输入流,注意路径不能包含中文名 26 | File file = new File(inputFilePath); 27 | if (!file.exists()) { 28 | throw new RuntimeException("测试数据有问题"); 29 | } 30 | try { 31 | fileInputStream = new FileInputStream(file); 32 | } catch (FileNotFoundException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | public ProblemResultItem call() throws Exception { 38 | ProblemResultItem item = new ProblemResultItem(); 39 | 40 | try { 41 | threadSystemIn.setThreadIn(fileInputStream); 42 | mainMethod.invoke(null, new Object[] { new String[0] }); 43 | 44 | item.setResult(new String(resultBuffer.removeBytes(Thread 45 | .currentThread().getId()))); 46 | item.setNormal(true); 47 | 48 | } catch (InvocationTargetException e) { 49 | Throwable throwable = e.getTargetException(); 50 | if (throwable instanceof OutOfMemoryError) { 51 | item.setMessage("内存溢出"); 52 | } else { 53 | item.setMessage(throwable.getMessage()); 54 | } 55 | item.setNormal(false); 56 | } catch (RuntimeException runtimeException) { 57 | item.setMessage(runtimeException.getMessage()); 58 | item.setNormal(false); 59 | } finally { 60 | threadSystemIn.removeAndCloseThreadIn(); 61 | } 62 | 63 | return item; 64 | } 65 | 66 | public void colseResource() { 67 | threadSystemIn.removeAndCloseThreadIn(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/constant/CommunicationSignal.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.constant; 2 | 3 | public final class CommunicationSignal { 4 | 5 | public final static class RequestSignal { 6 | public final static String CLOSE_SANDBOX = "CLOSE_SANDBOX"; 7 | public final static String SANDBOX_STATUS = "SANDBOX_STATUS"; 8 | public final static String IS_BUSY = "IS_BUSY"; 9 | public final static String REQUSET_JUDGED_PROBLEM = "REQUSET_JUDGED_PROBLEM"; 10 | } 11 | 12 | public final static class ResponseSignal { 13 | public final static String OK = "OK"; 14 | public final static String NO = "NO"; 15 | public final static String YES = "YES"; 16 | public final static String IDLE = "IDLE"; 17 | public final static String ERROR = "ERROR"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/constant/ConstantParameter.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.constant; 2 | 3 | public final class ConstantParameter { 4 | public final static int EXIT_VALUE = 999; 5 | } 6 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/core/Sandbox.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.core; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.io.PrintStream; 6 | import java.lang.Thread.UncaughtExceptionHandler; 7 | import java.lang.management.ManagementFactory; 8 | import java.lang.management.MemoryMXBean; 9 | import java.lang.reflect.Method; 10 | import java.lang.reflect.Modifier; 11 | import java.net.ServerSocket; 12 | import java.net.Socket; 13 | import java.util.List; 14 | import java.util.Scanner; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Executors; 17 | import java.util.concurrent.Future; 18 | import java.util.concurrent.ThreadFactory; 19 | 20 | import com.google.gson.Gson; 21 | 22 | import cn.superman.sandbox.callable.ProblemCallable; 23 | import cn.superman.sandbox.constant.CommunicationSignal; 24 | import cn.superman.sandbox.constant.ConstantParameter; 25 | import cn.superman.sandbox.core.classLoader.SandboxClassLoader; 26 | import cn.superman.sandbox.core.securityManager.SandboxSecurityManager; 27 | import cn.superman.sandbox.core.systemInStream.ThreadInputStream; 28 | import cn.superman.sandbox.core.systemOutStream.CacheOutputStream; 29 | import cn.superman.sandbox.dto.Problem; 30 | import cn.superman.sandbox.dto.ProblemResult; 31 | import cn.superman.sandbox.dto.ProblemResultItem; 32 | import cn.superman.sandbox.dto.Request; 33 | import cn.superman.sandbox.dto.Response; 34 | import cn.superman.sandbox.dto.SandBoxStatus; 35 | import cn.superman.sandbox.dto.SandboxInitData; 36 | 37 | public class Sandbox { 38 | // 每加载超过100个类后,就替换一个新的ClassLoader 39 | public static final int UPDATE_CLASSLOADER_GAP = 5; 40 | // 记录一共加载过的类数量 41 | private int loadClassCount = 0; 42 | private SandboxInitData sandboxInitData; 43 | private String pid = null; 44 | private ServerSocket serverSocket; 45 | private Socket communicateSocket; 46 | private SandboxClassLoader sandboxClassLoader; 47 | private Gson gson = null; 48 | private MemoryMXBean systemMemoryBean = null; 49 | private long beginStartTime = 0; 50 | // 表示当前进程是否在忙,如果在忙的话,就表示当前正在判题(这是当前正在的忙情况,以后可能会增加更多的情况) 51 | private boolean isBusy = false; 52 | private ProblemCallable problemCallable; 53 | // 用于重定向输出流,即代码输出的结果,将会输出到这个缓冲区中 54 | private volatile CacheOutputStream resultBuffer = new CacheOutputStream(); 55 | private volatile ThreadInputStream systemThreadIn = new ThreadInputStream(); 56 | // 用一个线程池去处理每个判题请求 57 | private ExecutorService problemThreadPool = Executors 58 | .newSingleThreadExecutor(new ThreadFactory() { 59 | 60 | @Override 61 | public Thread newThread(Runnable r) { 62 | Thread thread = new Thread(r); 63 | thread.setName("problemThreadPool"); 64 | thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 65 | 66 | @Override 67 | public void uncaughtException(Thread t, Throwable e) { 68 | writeResponse(null, 69 | CommunicationSignal.ResponseSignal.ERROR, 70 | null, e.getMessage()); 71 | } 72 | }); 73 | return thread; 74 | } 75 | }); 76 | // 用一个线程池去等待每个判题请求的结果返回 77 | private ExecutorService problemResultThreadPool = Executors 78 | .newSingleThreadExecutor(new ThreadFactory() { 79 | 80 | @Override 81 | public Thread newThread(Runnable r) { 82 | Thread thread = new Thread(r); 83 | thread.setName("problemResultThreadPool"); 84 | thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 85 | 86 | @Override 87 | public void uncaughtException(Thread t, Throwable e) { 88 | writeResponse(null, 89 | CommunicationSignal.ResponseSignal.ERROR, 90 | null, e.getMessage()); 91 | } 92 | }); 93 | return thread; 94 | } 95 | }); 96 | 97 | public static void main(String[] args) { 98 | new Sandbox(args); 99 | } 100 | 101 | private Sandbox(String[] args) { 102 | initSandbox(args); 103 | } 104 | 105 | /** 106 | * 沙箱初始化函数 107 | * @param args 初始化参数 108 | */ 109 | private void initSandbox(String[] args) { 110 | // 获取进程id,用于向外界反馈 111 | getPid(); 112 | // 沙箱环境准备 113 | SandboxInitData sandboxInitData = prepareBuildingNeed(args[0]); 114 | // 打开用于与外界沟通的通道 115 | openServerSocketWaitToConnect(sandboxInitData.getPort()); 116 | // 确保能与外界沟通之后,才开始准备执行class文件的环境 117 | buildEnvironment(sandboxInitData); 118 | // 等外界与沙箱,通过socket沟通上之后,就会进行业务上的沟通 119 | service(); 120 | 121 | } 122 | 123 | /** 124 | * 获取进程ID 125 | */ 126 | private void getPid() { 127 | String name = ManagementFactory.getRuntimeMXBean().getName(); 128 | pid = name.split("@")[0]; 129 | } 130 | 131 | /** 132 | * 准备沙箱初始化必要内容 133 | * @param sandboxInitJson 沙箱初始化JSON格式数据 134 | * @return 沙箱初始化所需要的信息 135 | */ 136 | private SandboxInitData prepareBuildingNeed(String sandboxInitJson) { 137 | gson = new Gson(); 138 | 139 | SandboxInitData sandboxInitData = gson.fromJson(sandboxInitJson, 140 | SandboxInitData.class); 141 | systemMemoryBean = ManagementFactory.getMemoryMXBean(); 142 | this.sandboxInitData = sandboxInitData; 143 | return sandboxInitData; 144 | } 145 | 146 | /** 147 | * 打开连接,等待建立连接 148 | * @param port 监听端口 149 | */ 150 | private void openServerSocketWaitToConnect(int port) { 151 | 152 | try { 153 | serverSocket = new ServerSocket(port); 154 | System.out.println("sandbox" + port + "wait"); 155 | communicateSocket = serverSocket.accept(); 156 | System.out.println("pid:" + pid); 157 | // 只与外部建立一个沟通的连接 158 | serverSocket.close(); 159 | } catch (IOException e) { 160 | System.err.println(e.getMessage()); 161 | throw new RuntimeException("无法打开沙箱端Socket,可能是端口被占用了"); 162 | } 163 | } 164 | 165 | /** 166 | * 建立沙箱环境 167 | * @param sandboxInitData 沙箱初始化信息 168 | */ 169 | private void buildEnvironment(SandboxInitData sandboxInitData) { 170 | sandboxClassLoader = new SandboxClassLoader( 171 | sandboxInitData.getClassFileRootPath()); 172 | beginStartTime = System.currentTimeMillis(); 173 | // 重定向输出流 174 | System.setOut(new PrintStream(resultBuffer)); 175 | // 重定向输入流 176 | System.setIn(systemThreadIn); 177 | } 178 | 179 | /** 180 | * 系统服务函数 181 | */ 182 | private void service() { 183 | try { 184 | Scanner scanner = new Scanner(communicateSocket.getInputStream()); 185 | // 必须建立了连接和流之后,才能设置这里的权限 186 | System.setSecurityManager(new SandboxSecurityManager()); 187 | String data = null; 188 | while (scanner.hasNext()) { 189 | // 每一次交流,都是一行一行的形式交流,即本次沟通内容发送完之后,发送方会在最后,加上一个"\n",表示发送完了这条消息 190 | data = scanner.nextLine(); 191 | Request request = gson.fromJson(data, Request.class); 192 | dispatchRequest(request); 193 | } 194 | scanner.close(); 195 | } catch (Exception e) { 196 | writeResponse(null, CommunicationSignal.ResponseSignal.ERROR, null, 197 | e.getMessage()); 198 | } 199 | } 200 | 201 | /** 202 | * 请求分发函数 203 | * @param request 请求内容 204 | * @throws IOException 205 | */ 206 | private void dispatchRequest(Request request) throws IOException { 207 | if (CommunicationSignal.RequestSignal.CLOSE_SANDBOX.equals(request 208 | .getCommand())) { 209 | closeSandboxService(request.getSignalId()); 210 | } else if (CommunicationSignal.RequestSignal.SANDBOX_STATUS 211 | .equals(request.getCommand())) { 212 | feedbackSandboxStatusService(request.getSignalId()); 213 | } else if (CommunicationSignal.RequestSignal.REQUSET_JUDGED_PROBLEM 214 | .equals(request.getCommand())) { 215 | if (loadClassCount >= UPDATE_CLASSLOADER_GAP) { 216 | loadClassCount = 0; 217 | // 重置类加载器,使得原有已经加载进内存的过期的类,可以得以释放 218 | sandboxClassLoader = new SandboxClassLoader( 219 | sandboxInitData.getClassFileRootPath()); 220 | System.gc(); 221 | } 222 | Future> processProblem = processProblem(request 223 | .getData()); 224 | returnJudgedProblemResult(request.getSignalId(), processProblem); 225 | loadClassCount++; 226 | } else if (CommunicationSignal.RequestSignal.IS_BUSY.equals(request 227 | .getCommand())) { 228 | checkBusy(request.getSignalId()); 229 | } 230 | } 231 | 232 | /** 233 | * 关闭沙箱服务 234 | * @param signalId 关闭信号 235 | */ 236 | private void closeSandboxService(String signalId) { 237 | writeResponse(signalId, CommunicationSignal.ResponseSignal.OK, 238 | CommunicationSignal.RequestSignal.CLOSE_SANDBOX, null); 239 | try { 240 | communicateSocket.close(); 241 | } catch (IOException e) { 242 | System.err.println(e); 243 | } 244 | closeSandbox(); 245 | } 246 | 247 | /** 248 | * 返回沙箱状态的服务 249 | * @param signalId 信号 250 | */ 251 | private void feedbackSandboxStatusService(String signalId) { 252 | SandBoxStatus sandBoxStatus = new SandBoxStatus(); 253 | sandBoxStatus.setPid(pid); 254 | sandBoxStatus.setBeginStartTime(beginStartTime); 255 | sandBoxStatus.setBusy(isBusy); 256 | // 由堆内存和非堆内存组成 257 | long useMemory = systemMemoryBean.getHeapMemoryUsage().getUsed() 258 | + systemMemoryBean.getNonHeapMemoryUsage().getUsed(); 259 | sandBoxStatus.setUseMemory(useMemory); 260 | // 由堆内存和非堆内存组成 261 | long maxMemory = systemMemoryBean.getHeapMemoryUsage().getMax() 262 | + systemMemoryBean.getNonHeapMemoryUsage().getMax(); 263 | sandBoxStatus.setMaxMemory(maxMemory); 264 | writeResponse(signalId, CommunicationSignal.ResponseSignal.OK, 265 | CommunicationSignal.RequestSignal.SANDBOX_STATUS, 266 | gson.toJson(sandBoxStatus)); 267 | 268 | } 269 | 270 | /** 271 | * 进行项目处理 272 | * @param problemJson 题目内容的JSON格式 273 | * @return 题目处理结果 274 | */ 275 | private Future> processProblem(String problemJson) { 276 | Problem problem = gson.fromJson(problemJson, Problem.class); 277 | try { 278 | Class mainClass = sandboxClassLoader.loadSandboxClass(problem 279 | .getClassFileName()); 280 | Method mainMethod = mainClass.getMethod("main", String[].class); 281 | if (!Modifier.isStatic(mainMethod.getModifiers())) 282 | throw new Exception("main方法不是静态方法"); 283 | 284 | mainMethod.setAccessible(true); 285 | problemCallable = new ProblemCallable(mainMethod, problem, 286 | resultBuffer, systemThreadIn); 287 | Future> submit = problemThreadPool 288 | .submit(problemCallable); 289 | isBusy = true; 290 | mainClass = null; 291 | return submit; 292 | } catch (ClassNotFoundException e) { 293 | writeResponse(null, CommunicationSignal.ResponseSignal.ERROR, null, 294 | e.getMessage()); 295 | } catch (Exception e) { 296 | writeResponse(null, CommunicationSignal.ResponseSignal.ERROR, null, 297 | e.getMessage()); 298 | } 299 | return null; 300 | } 301 | 302 | /** 303 | * 检查沙箱是否正忙 304 | * @param signalId 信号量 305 | */ 306 | private void checkBusy(String signalId) { 307 | String responseCommand = null; 308 | 309 | if (isBusy) { 310 | responseCommand = CommunicationSignal.ResponseSignal.YES; 311 | } else { 312 | responseCommand = CommunicationSignal.ResponseSignal.NO; 313 | } 314 | 315 | writeResponse(signalId, responseCommand, 316 | CommunicationSignal.RequestSignal.IS_BUSY, null); 317 | } 318 | 319 | /** 320 | * 返回题目运行结果 321 | * @param signalId 信号 322 | * @param processProblem 题目运行结果 323 | */ 324 | private void returnJudgedProblemResult(final String signalId, 325 | final Future> processProblem) { 326 | problemResultThreadPool.execute(new Runnable() { 327 | @Override 328 | public void run() { 329 | if (processProblem != null) { 330 | try { 331 | List resultItems = processProblem 332 | .get(); 333 | Problem problem = problemCallable.getProblem(); 334 | ProblemResult problemResult = new ProblemResult(); 335 | problemResult.setRunId(problem.getRunId()); 336 | problemResult.setResultItems(resultItems); 337 | 338 | writeResponse( 339 | signalId, 340 | CommunicationSignal.ResponseSignal.OK, 341 | CommunicationSignal.RequestSignal.REQUSET_JUDGED_PROBLEM, 342 | gson.toJson(problemResult)); 343 | isBusy = false; 344 | problemCallable = null; 345 | 346 | // 通知对方,主动告诉对方,自己已经空闲了,已经准备好下一次判题 347 | writeResponse(null, 348 | CommunicationSignal.ResponseSignal.IDLE, null, 349 | null); 350 | } catch (Exception e) { 351 | writeResponse(null, 352 | CommunicationSignal.ResponseSignal.ERROR, null, 353 | e.getMessage()); 354 | } 355 | } 356 | } 357 | }); 358 | } 359 | 360 | /** 361 | * 发送回复 362 | * @param signalId 信号 363 | * @param responseCommand 回复的命令 364 | * @param requestCommand 请求的命令 365 | * @param data 数据 366 | */ 367 | private void writeResponse(String signalId, String responseCommand, 368 | String requestCommand, String data) { 369 | try { 370 | OutputStream outputStream = communicateSocket.getOutputStream(); 371 | Response response = new Response(); 372 | response.setSignalId(signalId); 373 | response.setResponseCommand(responseCommand); 374 | response.setRequestCommand(requestCommand); 375 | response.setData(data); 376 | outputStream 377 | .write((gson.toJson(response) + "\n").getBytes("UTF-8")); 378 | } catch (IOException e) { 379 | System.err.println(e.getMessage()); 380 | throw new RuntimeException("无法对外输出数据"); 381 | } 382 | 383 | } 384 | 385 | /** 386 | * 关闭沙箱 387 | */ 388 | private void closeSandbox() { 389 | try { 390 | communicateSocket.close(); 391 | } catch (IOException e) { 392 | } 393 | System.exit(ConstantParameter.EXIT_VALUE); 394 | } 395 | } 396 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/core/classLoader/SandboxClassLoader.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.core.classLoader; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | 7 | public class SandboxClassLoader extends ClassLoader { 8 | private String classPath = null; 9 | 10 | public SandboxClassLoader(String classPath) { 11 | super(); 12 | this.classPath = classPath; 13 | } 14 | 15 | @Override 16 | protected Class findClass(String name) throws ClassNotFoundException { 17 | return loadSandboxClass(name); 18 | } 19 | 20 | public Class loadSandboxClass(String name) throws ClassNotFoundException { 21 | String classFilePath = classPath + File.separator + name + ".class"; 22 | FileInputStream inputStream = null; 23 | try { 24 | File file = new File(classFilePath); 25 | inputStream = new FileInputStream(file); 26 | byte[] classByte = new byte[(int) file.length()]; 27 | inputStream.read(classByte); 28 | 29 | return defineClass(name, classByte, 0, classByte.length); 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } finally { 33 | try { 34 | inputStream.close(); 35 | } catch (IOException e) { 36 | } 37 | } 38 | 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/core/securityManager/SandboxSecurityManager.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.core.securityManager; 2 | 3 | import java.io.FilePermission; 4 | import java.lang.reflect.ReflectPermission; 5 | import java.security.Permission; 6 | import java.security.SecurityPermission; 7 | import java.util.PropertyPermission; 8 | import java.util.logging.LoggingPermission; 9 | 10 | import cn.superman.sandbox.constant.ConstantParameter; 11 | 12 | public class SandboxSecurityManager extends SecurityManager { 13 | /** 14 | * 防止有人非法退出虚拟机 15 | */ 16 | @Override 17 | public void checkExit(int status) { 18 | if (status != ConstantParameter.EXIT_VALUE) { 19 | throw new RuntimeException("非法退出,不允许退出虚拟机"); 20 | } 21 | super.checkExit(status); 22 | } 23 | 24 | @Override 25 | public void checkPermission(Permission perm) { 26 | conformPermissionToSandbox(perm); 27 | } 28 | 29 | @Override 30 | public void checkPermission(Permission perm, Object context) { 31 | conformPermissionToSandbox(perm); 32 | } 33 | 34 | /** 35 | * 只给与必要的权限(比如读取,获取某些信息等),避免提交者进行非法操作。 36 | * 37 | * @param perm 38 | */ 39 | private void conformPermissionToSandbox(Permission perm) { 40 | if (perm instanceof SecurityPermission) { 41 | if (perm.getName().startsWith("getProperty")) { 42 | return; 43 | } 44 | } else if (perm instanceof PropertyPermission) { 45 | if (perm.getActions().equals("read")) { 46 | return; 47 | } 48 | } else if (perm instanceof FilePermission) { 49 | if (perm.getActions().equals("read")) { 50 | return; 51 | } 52 | } else if (perm instanceof RuntimePermission 53 | || perm instanceof ReflectPermission 54 | || perm instanceof LoggingPermission) { 55 | return; 56 | } 57 | 58 | throw new SecurityException(perm.toString() + "无法使用该权限"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/core/systemInStream/ThreadInputStream.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.core.systemInStream; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | public class ThreadInputStream extends InputStream { 7 | private volatile ThreadLocal localIn = new ThreadLocal(); 8 | 9 | @Override 10 | public int read() throws IOException { 11 | return localIn.get().read(); 12 | } 13 | 14 | public void setThreadIn(InputStream in) { 15 | localIn.set(in); 16 | } 17 | 18 | public void removeAndCloseThreadIn() { 19 | InputStream stream = localIn.get(); 20 | localIn.remove(); 21 | try { 22 | if (stream != null) { 23 | stream.close(); 24 | stream = null; 25 | } 26 | } catch (IOException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/core/systemOutStream/CacheOutputStream.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.core.systemOutStream; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | public class CacheOutputStream extends OutputStream { 8 | 9 | private volatile ThreadLocal localBytesCache = new ThreadLocal() { 10 | @Override 11 | protected ByteArrayOutputStream initialValue() { 12 | return new ByteArrayOutputStream(); 13 | } 14 | 15 | }; 16 | 17 | @Override 18 | public void write(int b) throws IOException { 19 | ByteArrayOutputStream byteBufferStream = localBytesCache.get(); 20 | byteBufferStream.write(b); 21 | } 22 | 23 | public byte[] removeBytes(long threadId) { 24 | ByteArrayOutputStream byteBufferStream = localBytesCache.get(); 25 | 26 | if (byteBufferStream == null) { 27 | return new byte[0]; 28 | } 29 | byte[] result = byteBufferStream.toByteArray(); 30 | // 因为这个可能以后还可以重用(因为线程时有反复重用的,所以这里只需要将里面的内容清空就可以了) 31 | byteBufferStream.reset(); 32 | return result; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/Problem.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem { 7 | private long timeLimit; 8 | private long memoryLimit; 9 | private String classFileName; 10 | private String runId; 11 | private List inputDataFilePathList = new ArrayList(); 12 | 13 | public long getTimeLimit() { 14 | return timeLimit; 15 | } 16 | 17 | public void setTimeLimit(long timeLimit) { 18 | this.timeLimit = timeLimit; 19 | } 20 | 21 | public long getMemoryLimit() { 22 | return memoryLimit; 23 | } 24 | 25 | public void setMemoryLimit(long memoryLimit) { 26 | this.memoryLimit = memoryLimit; 27 | } 28 | 29 | public String getClassFileName() { 30 | return classFileName; 31 | } 32 | 33 | public void setClassFileName(String classFileName) { 34 | this.classFileName = classFileName; 35 | } 36 | 37 | public String getRunId() { 38 | return runId; 39 | } 40 | 41 | public void setRunId(String runId) { 42 | this.runId = runId; 43 | } 44 | 45 | public List getInputDataFilePathList() { 46 | return inputDataFilePathList; 47 | } 48 | 49 | public void setInputDataFilePathList(List inputDataFilePathList) { 50 | this.inputDataFilePathList = inputDataFilePathList; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "Problem [timeLimit=" + timeLimit + ", memoryLimit=" 56 | + memoryLimit + ", classFileName=" + classFileName + ", runId=" 57 | + runId + ", inputDataFilePathList=" + inputDataFilePathList 58 | + "]"; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/ProblemResult.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ProblemResult { 7 | private String runId; 8 | private List resultItems = new ArrayList(); 9 | 10 | public String getRunId() { 11 | return runId; 12 | } 13 | 14 | public void setRunId(String runId) { 15 | this.runId = runId; 16 | } 17 | 18 | public List getResultItems() { 19 | return resultItems; 20 | } 21 | 22 | public void setResultItems(List resultItems) { 23 | this.resultItems = resultItems; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/ProblemResultItem.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | public class ProblemResultItem { 4 | private long useTime; 5 | private long useMemory; 6 | private String result; 7 | private String message; 8 | private boolean isNormal; 9 | private String inputFilePath; 10 | 11 | public long getUseTime() { 12 | return useTime; 13 | } 14 | 15 | public void setUseTime(long useTime) { 16 | this.useTime = useTime; 17 | } 18 | 19 | public long getUseMemory() { 20 | return useMemory; 21 | } 22 | 23 | public void setUseMemory(long useMemory) { 24 | this.useMemory = useMemory; 25 | } 26 | 27 | public String getResult() { 28 | return result; 29 | } 30 | 31 | public void setResult(String result) { 32 | this.result = result; 33 | } 34 | 35 | public String getMessage() { 36 | return message; 37 | } 38 | 39 | public void setMessage(String message) { 40 | this.message = message; 41 | } 42 | 43 | public boolean isNormal() { 44 | return isNormal; 45 | } 46 | 47 | public void setNormal(boolean isNormal) { 48 | this.isNormal = isNormal; 49 | } 50 | 51 | public String getInputFilePath() { 52 | return inputFilePath; 53 | } 54 | 55 | public void setInputFilePath(String inputFilePath) { 56 | this.inputFilePath = inputFilePath; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return "ProblemResultItem [useTime=" + useTime + ", useMemory=" 62 | + useMemory + ", result=" + result + ", message=" + message 63 | + ", isNormal=" + isNormal + ", inputFilePath=" + inputFilePath 64 | + "]"; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/Request.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | public class Request { 4 | private String command; 5 | private String data; 6 | private String signalId; 7 | 8 | public String getCommand() { 9 | return command; 10 | } 11 | 12 | public void setCommand(String command) { 13 | this.command = command; 14 | } 15 | 16 | public String getData() { 17 | return data; 18 | } 19 | 20 | public void setData(String data) { 21 | this.data = data; 22 | } 23 | 24 | public String getSignalId() { 25 | return signalId; 26 | } 27 | 28 | public void setSignalId(String signalId) { 29 | this.signalId = signalId; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/Response.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | public class Response { 4 | private String requestCommand; 5 | private String responseCommand; 6 | private String data; 7 | private String signalId; 8 | 9 | public String getResponseCommand() { 10 | return responseCommand; 11 | } 12 | 13 | public void setResponseCommand(String responseCommand) { 14 | this.responseCommand = responseCommand; 15 | } 16 | 17 | public String getRequestCommand() { 18 | return requestCommand; 19 | } 20 | 21 | public void setRequestCommand(String requestCommand) { 22 | this.requestCommand = requestCommand; 23 | } 24 | 25 | public String getData() { 26 | return data; 27 | } 28 | 29 | public void setData(String data) { 30 | this.data = data; 31 | } 32 | 33 | public String getSignalId() { 34 | return signalId; 35 | } 36 | 37 | public void setSignalId(String signalId) { 38 | this.signalId = signalId; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/SandBoxStatus.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | public class SandBoxStatus { 4 | private String pid; 5 | private long useMemory; 6 | private long maxMemory; 7 | private long beginStartTime; 8 | private boolean isBusy; 9 | 10 | public String getPid() { 11 | return pid; 12 | } 13 | 14 | public void setPid(String pid) { 15 | this.pid = pid; 16 | } 17 | 18 | public long getUseMemory() { 19 | return useMemory; 20 | } 21 | 22 | public long getMaxMemory() { 23 | return maxMemory; 24 | } 25 | 26 | public void setMaxMemory(long maxMemory) { 27 | this.maxMemory = maxMemory; 28 | } 29 | 30 | public void setUseMemory(long useMemory) { 31 | this.useMemory = useMemory; 32 | } 33 | 34 | public long getBeginStartTime() { 35 | return beginStartTime; 36 | } 37 | 38 | public void setBeginStartTime(long beginStartTime) { 39 | this.beginStartTime = beginStartTime; 40 | } 41 | 42 | public boolean isBusy() { 43 | return isBusy; 44 | } 45 | 46 | public void setBusy(boolean isBusy) { 47 | this.isBusy = isBusy; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/cn/superman/sandbox/dto/SandboxInitData.java: -------------------------------------------------------------------------------- 1 | package cn.superman.sandbox.dto; 2 | 3 | public class SandboxInitData { 4 | private int port; 5 | private String classFileRootPath; 6 | 7 | public int getPort() { 8 | return port; 9 | } 10 | 11 | public void setPort(int port) { 12 | this.port = port; 13 | } 14 | 15 | public String getClassFileRootPath() { 16 | return classFileRootPath; 17 | } 18 | 19 | public void setClassFileRootPath(String classFileRootPath) { 20 | this.classFileRootPath = classFileRootPath; 21 | } 22 | 23 | } 24 | --------------------------------------------------------------------------------