1

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

8
  • 2
    The solution is to learn and write some Scala. Commented Nov 25, 2012 at 19:30
  • No. You can't. Please, post why you need them in the same file (besides "it's homework"). Commented Nov 25, 2012 at 19:32
  • @MarkoTopolnik Indeed, and I'm sure I'd learn a lot. It's just that I don't really have the time to fully understand, implement and test a kd-tree library by myself right now, and since efficiency is not one of the central homework requirements, I'd rather have O(n^2) if I can't find one Commented Nov 25, 2012 at 19:35
  • 1
    it's still unclear where does requirement of having java and scala code in the same file come from. Every popular scala build tool support joint compilation of .scala and .java files. Commented Nov 25, 2012 at 19:38
  • @EmilIvanov Well, it's a requirement because my teacher has made it so, I guess? I realise it's a pretty arbitrary one, especially since we can use external libraries, as long as we include them in the file Commented Nov 25, 2012 at 19:38

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This seems very promising!
3

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)

Comments

1

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.

7 Comments

If I understoo what BCEL does in my quick skim, wouldn't this shift the work of implementing the original library in scala to implementing BCEL? Also, I can't send compiled code, only a single scala source. But I pretty much predicted this would be impossible
@scala_newbie it's impossible to achieve on source-file level
@om-nom-nom theoretically, wouldn't it be possible if there was a scala implementation of the JVM? Of course, I'm not expecting anyone to have a motive for implementing such a thing, it seems pretty pointless
@scala_newbie I don't think language in which implemented JVM (it's mostly C/C++ as far as I know) somehow affect this issue
@om-nom-nom What I meant is you could have a JVM running inside another JVM. The base JVM would, of course, be the OS's, the other, implemented in scala, would be free to execute any arbitrary bytecode, including the library bytecode
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.