How to disassemble and decompile Scala code (javap, scalac, jad)
This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 14.6, “How to disassemble and decompile Scala code.”
Back to topProblem
In the process of learning Scala, or trying to understand a particular problem, you want to examine the source code and bytecode the Scala compiler generates from your original source code.
Back to topSolution
You can use several different approaches to see how your Scala source code is translated:
Java’s javap command doesn’t show private members (by default)
As I was just reminded, Java’s javap
command doesn’t show private members by default. You have to use the -p
option of javap
to see private members.
I was just reminded of that when using the Scala REPL. Given this Person
class with a private constructor field named name
:
class Person(private var name: String)
javap
without the -p
option shows this:
You can run the `javap` command inside the Scala REPL
As shown in the image, I was just reminded that you can run javap
inside the Scala REPL. The REPL help command shows some other things you can do:
scala> :help All commands can be abbreviated, e.g., :he instead of :help. :edit <id>|<line> edit history :help [command] print this summary or command-specific help :history [num] show the history (optional num is commands to show) :h? <string> search the history :imports [name name ...] show import history, identifying sources of names :implicits [-v] show the implicits in scope :javap <path|class> disassemble a file or class name :line <id>|<line> place line(s) at the end of history :load <path> interpret lines in a file :paste [-raw] [path] enter paste mode or paste a file :power enable power user mode :quit exit the interpreter :replay [options] reset the repl and replay all previous commands :require <path> add a jar to the classpath :reset [options] reset the repl to its initial state, forgetting all session entries :save <path> save replayable session to a file :sh <command line> run a shell command (result is implicitly => List[String]) :settings <options> update compiler options, if possible; see reset :silent disable/enable automatic printing of results :type [-v] <expr> display the type of an expression without evaluating it :kind [-v] <type> display the kind of a type. see also :help kind :warnings show the suppressed warnings from the most recent line which had any
More Scala/javap examples
Here are a couple more javap
examples in the Scala REPL that help to show what details are available:
scala> class Person (var name: String, var age: Int) defined class Person scala> :javap -public Person Compiled from "<console>" public class $line3.$read$$iw$$iw$Person { public java.lang.String name(); public void name_$eq(java.lang.String); public int age(); public void age_$eq(int); public $line3.$read$$iw$$iw$Person(java.lang.String, int); } scala> :javap -private Person Compiled from "<console>" public class $line3.$read$$iw$$iw$Person { private java.lang.String name; private int age; public java.lang.String name(); public void name_$eq(java.lang.String); public int age(); public void age_$eq(int); public $line3.$read$$iw$$iw$Person(java.lang.String, int); }
javap help
Finally, here’s the output from the javap -help
command that helps to explain that output:
> javap -help Usage: javap <options> <classes> where possible options include: -help --help -? Print this usage message -version Version information -v -verbose Print additional information -l Print line number and local variable tables -public Show only public classes and members -protected Show protected/public classes and members -package Show package/protected/public classes and members (default) -p -private Show all classes and members -c Disassemble the code -s Print internal type signatures -sysinfo Show system info (path, size, date, MD5 hash) of class being processed -constants Show final constants -classpath <path> Specify where to find user class files -cp <path> Specify where to find user class files -bootclasspath <path> Override location of bootstrap class files
If you ever want to use javap inside the Scala REPL, I hope this information is helpful.
A look at how the Scala `lazy val` syntax gets converted into Java code (bytecode)
I don’t have any major conclusions to share in this blog post, but ... what I was curious about is how Scala implements “lazy val” fields. That is, when the Scala code I write is translated into a .class file and bytecode that a JVM can understand, what does that resulting code look like?
A Scala “Hello, world” video tutorial
Yesterday I created a video tutorial on the Scala REPL and var & val variable types, and today I took a little time to create a new "Hello, world" Scala video tutorial. Without any further ado, here's the video:
If you're in the market for a Scala "Hello, world" tutorial, I hope you like it.
Converting a Scala class file to decompiled Java source code
As a Scala newbie, I'm curious about how the process of converting a Scala class back to Java source code works. What I really want to see is how my Scala source code is converted to Java source code. Besides plain old curiosity, I think that understanding more about how Scala works can also be very important to my understanding of Scala (such as the apply() method, and so on).
Thu, May 9, 2002
Here's a little tutorial on how to disassemble Java class files with javap -c
.