Include java source in scala file [duplicate]

情到浓时终转凉″ 提交于 2020-01-06 03:03:39

问题


Possible Duplicate:
Compile file containing java and scala code

I'm aware that Scala can easily use Java classes. However, is it possible to include Java source inside a scala file and have it compile with scalac, in any way?

Alternatively, is it possible to include javac-compiled bytecode as a bytearray in the source, and import from it (yuck, yes)?

This is for homework, so, no, I can't have separate files, and it must compile with scalac file.scala, with no additional arguments. To clarify, this is a hard requisite by my teacher


回答1:


If you want to write a literal byte array in Scala code, it is easy to go from that to a normal Java class, simply by calling Classloader.defineClass. This means that you need to make your own subclass of ClassLoader that exposes one of the overloads of this method. This is all doable in Scala without much trouble.

If you carefully prepare this, you may even get type safety, by making your class-from-bytearray implement an interface that you have defined in Scala. I don't know the exact details on this, but I remember it was possible for a Java class to subclass/implement something defined in Scala. Failing that, you certainly have reflection at your disposal.




回答2:


I just wrote a simple example

say you have a java class like this

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

Then you write some scala code to turn that into a byte array

import java.io.{FileInputStream, FileOutputStream}
import collection.mutable.ArrayBuffer

val in = new FileInputStream("HelloWorld.class")
val out = new FileOutputStream("HelloWorldBytes.scala")

Console.withOut(out) {
  var data = in.read()
  print("val helloWorldBytes = Array[Byte](")
  print(if(data < 128) data else data - 256)
  data = in.read()
  while(data >= 0) {
    print(", ")
    print(if(data < 128) data else data - 256)
    data = in.read()
  }
  println(")")
}


in.close()
out.close()

And then you can use it like this

val helloWorldBytes = Array[Byte](...)

object Loader extends ClassLoader {
  override
  def findClass(name: String): Class[_] =
    if(name == "HelloWorld") defineClass(name, helloWorldBytes, 0, helloWorldBytes.size)
    else super.findClass(name)
}

val helloWorld = Loader.loadClass("HelloWorld")
helloWorld.getDeclaredMethod("main", classOf[Array[String]]).invoke(null,null)



回答3:


You could use BCEL and specify a Javac-derived instruction list in the Scala, but I can't really imagine how this is practical in any way. The simplest way to do what you want is to use (say) the Maven scala plugin to compile both Java and Scala files together.



来源:https://stackoverflow.com/questions/13554617/include-java-source-in-scala-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!