Compiler et exécuter le fichier Scala dans un programme Java


Je travaille sur un programme Java qui prend un programme Scala dans un fichier texte, le compile (à l'intérieur de Java), puis l'exécute (également à l'intérieur de Java). Je ne pouvais pas trouver un moyen propre de mettre en œuvre cela. Pour compiler, j'ai essayé d'utiliser le code comme indiqué ci-dessous:

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());

Cependant, j'obtiens une erreur (réduite pour plus de clarté):

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)

Je ne comprenais pas ce qui causait cela ou comment réparer. Comme solution de contournement temporaire, j'ai essayé de compiler le code Scala en externe et de l'appeler en Java via:

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

Bien que je pense que le code s'exécute, il n'est pas interactif avec le programme Java comme je le voudrais. Par exemple, lors de l'exécution du programme Scala (à l'intérieur de Java) si le programme Scala voulait que l'utilisateur tape une chaîne dans la console, le programme Java devrait faire la même chose essentiellement.

Toute orientation est appréciée.

Author: ZaydH, 2016-03-15

1 answers

Le moyen le plus simple est probablement d'utiliser une petite bibliothèque wrapper qui s'occupe de choses comme les chemins de classe, etc. Par exemple, il existe une petite bibliothèque Twitter Util-Eval (source).

Voici un exemple:

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);
  }
}

Si vous voulez faire cuire votre propre compilateur et wrapper runner, cela implique un peu plus, vous devrez compiler dans des fichiers virtuels, puis les charger dans un chargeur de classe (voir par exemple iciet ici).

 2
Author: 0__, 2016-03-15 13:47:25