Extract scala source code from jar
Asked Answered
S

2

8

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!

Salesperson answered 2/3, 2016 at 2:38 Comment(1)
I have a same issueRalli
S
3

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.

Spokeshave answered 2/3, 2016 at 7:8 Comment(2)
Is this still current in 2018?Haggis
@Haggis Yes, so far as I know. (Except writing the decompiler would be more complicated now, at least if you wanted to support both Scala 2.12 and previous versions.)Spokeshave
W
2

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.

Withhold answered 14/9, 2020 at 12:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.