3

Javaコードを純粋なscalaに移植しようとしているので、この点で助けていただければ幸いです。

以下のコードは、最初にビジネス ロジックを Java コードに変換することによって機能します。ここでは、freemarker テンプレートを使用して、テンプレート ベースのコード生成を行っています。ファイルの作成後、Java comiler を使用してコードをコンパイルし、jar ファイルを作成します。このファイルは一時ディレクトリに保持されます。

現在、javax.tools.*ランタイム コンパイルを提供するパッケージを使用しています。そのアプローチに相当する Scala は何ですか? freemarker テンプレートを使用して純粋な Scala コードを生成し、Scala コンパイルを実行して jar ファイルを作成したいと考えています。

以下は、これを実現するために使用しているサンプル Java コードです。

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
    StringBuilder builder = new StringBuilder();
    builder.append(service.getConfig().getProp("coreLib"));
    builder.append(";" +result.getCodeContext().getOmClasspath());
    builder.append(";" +jarBuilder.toString());
    builder.append(";" +service.getConfig().getProp("tempCodeGen"));
    String[] compileOptions = new String[]{"-d", result.getCodeContext().getOmClasspath(),"-cp",builder.toString()} ;
    Iterable<String> compilationOptionss = Arrays.asList(compileOptions);
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, compilationOptionss, null, compilationUnits) ;
    boolean status = compilerTask.call();
4

4 に答える 4

3

プロジェクトをコンパイルして jar にパッケージ化するための、私自身のコードからのいくつかのメソッドを次に示します。洗練された、または適切にコメントされているとは言えませんが、どこから始める必要があるかを示してくれることを願っています. これはパフォーマンスが重要ではないため、String Builder を使用する必要はないと思います。

def buildAll(name: String, projDir: String, mainClass: String = ""): Unit =
{
  import scala.tools.nsc.{Settings,Global}
  val relSrc : List[String] = List()
  val maniVersion = "None"
  def targDir: String = projDir + "/targ"
  def srcDir: String = projDir + "/src"
  def srcDirs: List[String] = srcDir :: relSrc

  import java.io._
  val sings = new scala.tools.nsc.Settings     
  new File(targDir).mkdir 
  sings.outputDirs.setSingleOutput(targDir.toString)     
  val comp = new Global(sings)      
  val crun: comp.Run  = new comp.Run
  def getList(fName: String): List[String] =
  {
     println("starting getList " + fName)
     val file = new File(fName)
     if (file.isDirectory) file.listFiles.toList.flatMap(i => getList(fName + "/" + i.getName))
     else List(fName)
  }  

  crun.compile(srcDirs.flatMap(i => getList(i))) 
  import sys.process._
  ("cp -r /sdat/projects/ScalaLibs/scala " + targDir + "/scala").!

  import java.util.jar._
  val manif = new Manifest
  val mf = manif.getMainAttributes
  mf.put(Attributes.Name.MANIFEST_VERSION, maniVersion)
  if (mainClass != "") mf.put(Attributes.Name.MAIN_CLASS, mainClass)
  val jarName = name + ".jar"
  val jarOut: JarOutputStream = new JarOutputStream(new FileOutputStream(projDir + "/" + jarName), manif)  
  AddAllToJar(targDir, jarOut)      
  jarOut.close   
}   

def addToJar(jarOut: JarOutputStream, file: File, reldir: String): Unit =
{
  val fName = reldir + file.getName         
  val fNameMod = if (file.isDirectory) fName + "/" else fName
  val entry = new JarEntry(fNameMod)
  entry.setTime(file.lastModified)         
  jarOut.putNextEntry(entry)
  if (file.isDirectory)
  {
     jarOut.closeEntry
     file.listFiles.foreach(i => addToJar(jarOut, i, fName + "/"))
  }
  else
  {         
     var buf = new Array[Byte](1024)
     val in = new FileInputStream(file)
     Stream.continually(in.read(buf)).takeWhile(_ != -1).foreach(jarOut.write(buf, 0, _))
     in.close
     jarOut.closeEntry()
  }         
}
def AddAllToJar(targDir: String, jarOut: JarOutputStream): Unit =
  new java.io.File(targDir).listFiles.foreach(i => addToJar(jarOut, i, ""))

Scala Compiler をビルド パスに追加する必要があります。Scala コンパイラはソースファイルのリストを取得し、出力ディレクトリに設定されたディレクトリにコンパイル済みのクラス ファイルを生成します。ただし、コンパイラの全機能を把握することは主要なタスクです。

于 2013-10-21T13:51:28.410 に答える
1

生成されたコードを実行時にコンパイルしたい場合、最も簡単な解決策はtwitter eval ユーティリティです

于 2013-10-22T06:48:14.147 に答える