2016-03-15 49 views
2

我正在研究一個Java程序,該程序需要一個文本文件中的Scala程序,將其編譯(在Java內部),然後運行它(也在Java內部)。我找不出一個乾淨的方式來實現這一點。要編譯,我試圖用代碼如下所示:在Java程序中編譯並運行Scala文件

import scala.collection.JavaConversions; 
import scala.tools.nsc.Global; 
import scala.tools.nsc.Settings; 

Global g = new Global(new Settings()); 
Global.Run run = g.new Run(); 
List<String> fileNames = new ArrayList<String>(Arrays.asList("Hello.scala")); 

run.compile(JavaConversions.asScalaBuffer(fileNames).toList()); 

不過,我得到一個錯誤(減少清晰度):

error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by C:\Program Files\Java\jdk1.7.0_79\jre\lib\rt.jar(java/lang/Object.class) 

我不明白是什麼導致這或如何解決。作爲暫時的解決辦法,我試圖通過外部編譯Scala代碼,並呼籲在Java中:

Runtime rt = Runtime.getRuntime(); 
Process pr = rt.exec("java -cp scala-library.jar;. Hello"); 

雖然我覺得代碼運行,這是不是因爲我想在Java程序的交互。例如,如果Scala程序希望用戶在控制檯中輸入一個字符串,那麼當運行Scala程序(在Java內部)時,Java程序應該做同樣的事情。

任何指導表示讚賞。

回答

2

最簡單的方法可能就是使用一個小的包裝庫來處理類路徑等問題。例如,有一個小型庫Twitter Util-Evalsource)。

下面是一個例子:

package foo; 

import com.twitter.util.Eval; 

public class Test { 
    public static void main(String[] args) { 
    final Eval eval = new Eval(); 
    final int result = eval.apply("3 + 4", true); 
    System.out.println("Result: " + result); 
    } 
} 

如果你想烤自己的編譯器和亞軍的包裝,這涉及多一點,你將需要編譯到虛擬文件,然後將其裝入類加載器(參見例如herehere)。

+0

當我將Scala代碼作爲字符串直接應用到應用程序中時,我不會從對象中打印出「main」方法的結果。我可以通過「eval.compile(scalaCode.toString());」來編譯它。但是,從那裏我無法運行它。如果你想讓我發佈我的Scala代碼作爲問題的一部分,我可以這樣做。 – ZaydH

+0

爲什麼你不追加調用?就像''對象Foo extends App {println(「hello」)}'' - >'「object Foo {...}; Foo.main(new Array [String](0))'。 –

+0

''我最終使用從我的Java程序中調用該對象內的函數。 – ZaydH