#scala #jar #decompiling #decompiler
#java #scala #jar #декомпилятор #scalac
Вопрос:
Итак, у меня есть файл jar, который содержит scala в качестве исходного кода, и я потерял исходный код. Есть ли способ преобразовать файлы классов в jar в функции и классы scala вместо классов Java, создаваемых компилятором?
Я попытался использовать для этого декомпилятор, и это дает мне только Java-код, который не имеет смысла.
Заранее благодарю вас!
Комментарии:
1. У меня такая же проблема
Ответ №1:
Вам понадобится декомпилятор, специфичный для Scala. Нет причин, по которым его нельзя было бы написать, но это потребовало бы больших усилий, и, насколько я знаю, никто на самом деле этого не сделал. Конечно, это не привело бы к созданию точно исходного кода, так же как декомпиляторы для других языков этого не делают.
Комментарии:
1. Это все еще актуально в 2018 году?
2. @kaqqao Да, насколько я знаю. (За исключением того, что написание декомпилятора теперь было бы более сложным, по крайней мере, если бы вы хотели поддерживать как Scala 2.12, так и предыдущие версии.)
Ответ №2:
Scala компилируется в байт-код JVM, который является той же целью компиляции, что и Java. Если декомпилятор явно не нацелен на Scala, декомпиляция в Java имеет смысл.
Чтобы дополнить информацию в ответе Алексея Романова, которая все еще актуальна и действительна для Scala 2, я хотел бы добавить, что начиная с Scala 3 (он же Dotty, название его разработки), Scala сначала компилируется в промежуточное представление TASTy (которое добавляет типизированную информацию абстрактного синтаксического дерева в скомпилированные файлы классов — отсюда и название).
Вы можете увидеть презентацию о TASTy и ее роли в конвейере компилятора в этом интересном докладе на Scala Days 2019.
Как упоминалось в докладе, Dotty изначально предлагает возможность декомпиляции выходных данных компиляции (TASTy classfiles).
В качестве простого эксперимента давайте рассмотрим эту очень простую программу в файле Main.scala
:
object Main {
def main(args: Array[String]): Unit = {
println("hello, world")
}
}
Выполнение dotc Main.scala
на нем приводит к ожидаемому результату ( .class
файл для Main
класса, один для Main
объекта и .tasty
файл), который может быть отправлен обратно в (de) компилятор с -decompile
опцией следующим образом:
dotc -decompile Main
Вывод этой команды следующий:
/** 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")
}
Вы можете следовать инструкциям здесь, чтобы начать работу с Dotty и выполнить тот же эксперимент, что и я, который был запущен с Dotty 0.27.0-RC1.