2016-04-14 83 views
0

如何運行Java代碼,哪位用戶向我發送請求?如何在Java中編譯和運行用戶代碼?

我需要從用戶的代碼,使用我的一些類,運行它並採取結果。

+5

對於初學者:對安全性變得極度偏執。 –

+0

@LouisWasserman當然,但編譯和運行用戶代碼是我的想法的基礎。 – z17

+0

是否需要編譯程序中的代碼?提供用戶可以編程的接口,編譯自己的實現,然後在程序中註冊它們的實現(.jar文件)是一種更常見的技術。當您必須註冊JDBC驅動程序時,這是啓用JDBC的程序的工作方式。 – Samuel

回答

0

一種非常原始的方法是這樣的:

String code = request.getParameter("code"); 
String className = "Code" + DigestUtils.sha1hex(code); 
String classCode = "" 
    + "public class " + className + " implements Runnable {\n" + 
    + " public void run() {\n" + 
    + code + "\n" 
    + " }\n" 
    + "}\n"; 
Files.write(new File(className + ".java"), code, StandardCharsets.UTF_8); 

Runtime.getRuntime().exec("javac " + className + ".java"); 

Class<?> clazz = Class.forName(className); 
((Runnable)clazz.newInstance()).run(); 

假設當前目錄是在classpath中,並進一步假設點播類加載器加載類,這或類似的東西應該工作,至少例如你的System.out

使用此代碼時,請注意,上傳的代碼可能會執行任何操作,包括調用System.exit(1),讀取文件系統中的所有文件,在計算機上啓動僵屍網絡等。

而不是代碼的最後兩行,你也可以這樣做:

Runtime.getRuntime().exec("java " + className); 

(或它的一些變化,然後讓你捕捉System.outSystem.err,所以你可以餵它們回HTTP客戶端,這也可以防止來自System.exit的任何危險,因此只剩下許多其他漏洞。)

+0

我已經完成了,就像你以第二種方式寫的一樣。謝謝。 – z17

+0

關於安全性:可以在某個容器中運行此代碼,在這個容器中沒有人不能做任何想法。 此外,我已閱讀Java編譯API,但尚未嘗試。 – z17