2009-11-24 43 views
2

我想重溫一個關於類的內存「編譯」的舊問題。自從我問了一些問題(並且有些回答)以來,大約有1/2年過去了,我想重新提出這個問題,看看是否會有新的東西出現(所以不會,我不認爲這是重複的) 。java內存中實時類編譯(和加載)

老問題可以在這裏找到:On-the-fly, in-memory java code compilation for Java 5 and Java 6 - 我建議在回答這個問題之前閱讀它(和答案)。

我非常滿意beanshell做一個Java類的字符串到實際的Class對象的繁重工作。然而,beanshell在2.0b4版本上已經有很多年了,它的侷限性(沒有構造函數,甚至沒有默認值;沒有泛型,沒有for-each,沒有枚舉...)很煩人。

提醒 - 這是用作調試接口,因此性能考慮可以忽略不計。但是,我無法重新啓動服務器,無法將類文件發送到位置,並且JSP對我來說是一個非常糟糕的選擇(我不會在這裏解釋原因)。此外,最終產品必須是一個類(或該類的一個對象),所以我可以傳遞它。

一些限制:我不能有一個JDK,所以沒有javax.tools.JavaCompiler。我沒有JSP,因爲我沒有tomcat或其他「真正的」web容器。 Java 5語法支持將會很棒,尤其是泛型,枚舉和參數化。對默認構造函數的支持將會非常好。

任何想法?

編輯1:我剛剛發現有一個在beanshell中有構造函數的循環方法 - 但是你必須聲明它們爲「public void XXX(){...}」而不是通常的方式「public XXX(){...}」。

回答

0

我結束了使用Bean Shell。這並不完美,但它解決了99%的問題。

0

難道你不能複製到tools.jar並獲取javax.tools.JavaCompiler並將其添加到類路徑?或者它是一個授權問題。

此代碼,並在類路徑中的tools.jar,似乎工作:

import java.io.File; 
import java.io.IOException; 
import java.util.Arrays; 
import javax.tools.JavaCompiler; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 


public class Main 
{ 
    public static void main(final String[] argv) 
     throws IOException 
    { 
     final File[]        files; 
     final JavaCompiler      compiler; 
     final StandardJavaFileManager   fileManager; 
     final Iterable<? extends JavaFileObject> compilationUnits; 

     files = new File[] 
     { 
      new File(argv[0]), 
     };   
     compiler   = ToolProvider.getSystemJavaCompiler(); 
     fileManager  = compiler.getStandardFileManager(null, null, null); 
     compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files)); 

     compiler.getTask(null, fileManager, null, null, null, compilationUnits).call(); 
     fileManager.close(); 
    } 
} 
+0

號碼許可問題。另外,客戶端可以更改我的服務器運行的JRE,所以這也是兼容性問題。 – 2009-11-25 09:54:48

2

如果你不能捆綁SUN JDK的tools.jar由於授權方面的原因,也許你可以包括了Eclipse JDT編譯內核,而不是見

http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm

這是如Jetty Web服務器的JSP實現的功能。

+0

因爲我使用碼頭,我可能會考慮這一點。好決定。 – 2009-11-25 09:51:02

+0

嗯,我做到了。這需要我:1。直接依靠JDT,這對我來說是一個問題(組織級別),或者依賴於不能保證不會改變的碼頭內部。無論如何感謝 – 2009-11-26 11:16:53

0

我記得很久以前讀過關於字節碼工程庫(BCEL)的內容,當時Java 1.4已經風靡一時。見http://jakarta.apache.org/bcel/index.html。我從來沒有使用它,所以我只提及它,因爲它似乎接近你所問的(它工作,或者至少與舊的虛擬機一起工作),我還沒有看到任何人提到它。

+0

會考慮它。聽起來不像是一個有效的解決方案 - 太多的開銷。 – 2009-11-25 09:52:47

0

是否有一個特定的原因爲什麼它必須是一個Java字符串產生類/對象?我自發的反應是,JRuby就是你正在尋找的東西 - 它似乎是一個非常堅實的平臺,Ruby具有元編程的強大傳統。

+0

必須是一個Java字符串,因爲這是所有開發人員在這裏知道的。我想寫一個「插件」,它將連接到正在運行的服務器並幫助調試它(生成日誌消息,查詢內部結構等)。強制每個人學習ruby都會在開始之前將其廢棄(沒有人會學習 - 沒有人會使用它)。 – 2009-11-25 09:54:04

+0

多麼悲傷 - 它會像你的手套一樣適合你。正如您已經注意到的,Java通常不用於腳本編寫是有原因的。我認爲Groovy和JavaScript(比Ruby更多的Java-ish)也不可能? – gustafc 2009-11-25 11:18:01

+0

@gustafc:是的,出於同樣的原因。 – 2009-11-25 11:26:20