2016-03-15 204 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