Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract scala source code from jar

So I have a jar file that contains scala as the source code and I have lost the original code. Is there a way to convert the class files in the jar to scala functions and classes instead of the java classes the compiler makes?

I have tried using a decompiler on it and it only gives me the java code that makes zero sense.

Thank you in advance!

like image 319
user3003510 Avatar asked Mar 02 '16 02:03

user3003510


2 Answers

You'd need a Scala-specific decompiler. There is no reason one couldn't be written, but it would be a large effort and so far as I know nobody has actually done it. Of course, it wouldn't produce exactly the original code, just as decompilers for other languages don't.

like image 184
Alexey Romanov Avatar answered Oct 04 '22 00:10

Alexey Romanov


Scala compiles to JVM bytecode, which is the same compilation target as Java. Unless the decompiler targets Scala explicitly, decompiling to Java makes sense.

To complement the information in Alexey Romanov's answer, which is still current and valid for Scala 2, I'd like to add that since Scala 3 (a.k.a. Dotty, its development name), Scala first compiles to an intermediate representation, TASTy (which adds Typed Abstract Syntax tree information to the compiled classfiles -- hence the name).

You can see an presentation about TASTy and its role in the compiler pipeline in this interesting talk at Scala Days 2019.

As mentioned in the talk, Dotty natively offers the possibility of decompiling the compilation output (TASTy + classfiles).

As a simple experiment, let's consider this very simple program in a file Main.scala:

object Main {

  def main(args: Array[String]): Unit = {
    println("hello, world")
  }

}

Running dotc Main.scala on it produces the expected output (a .class file for the Main class, one for the Main object and a .tasty file), which can be fed back into the (de)compiler with the -decompile option, as follows:

dotc -decompile Main

The output of this command is the following:

/** Decompiled from ./Main.tasty */
@scala.annotation.internal.SourceFile("Main.scala") object Main {
  def main(args: scala.Array[scala.Predef.String]): scala.Unit = scala.Predef.println("hello, world")
}

You can follow the instructions here to get started with Dotty and perform the same experiment as I did, which was run with Dotty 0.27.0-RC1.

like image 43
stefanobaghino Avatar answered Oct 03 '22 23:10

stefanobaghino