Skip to content

REPL :javap doesn't work on JDK 16+ unless you pass extra flags #12378

Open
@lrytz

Description

@lrytz
Welcome to Scala 2.13.5 (OpenJDK 64-Bit Server VM, Java 16).
Type in expressions for evaluation. Or try :help.

scala> :javap scala.Some
java.lang.IllegalAccessException: class scala.tools.nsc.interpreter.shell.JavapTask cannot access class com.sun.tools.javap.JavapFileManager (in module jdk.jdeps) because module jdk.jdeps does not export com.sun.tools.javap to unnamed module @324e4822
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385)
	at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:687)
	at java.base/java.lang.reflect.Method.invoke(Method.java:559)
	at scala.tools.nsc.interpreter.shell.JavapTask.<init>(JavapClass.scala:498)

From what I understand, the complication is that we need to make javap read a class from the repl's in-memory representation / class loader.

It seems the only accessible API is ToolProvider which only has a run method. I assume we cannot make it search classes in a custom class loader through this.

Personally, I'd be fine throwing out :javap in favor of :asmp which would be easy to implement

scala> :power
Power mode enabled. :phase is at typer.
import scala.tools.nsc._, intp.global._, definitions._
Try :help or completions for vals._ and power._

scala> class HalloVelo
class HalloVelo

scala> scala.tools.nsc.backend.jvm.AsmUtils.traceClass(intp.classLoader.classBytes("HalloVelo"))
Bytecode for class $line31/$read$$iw$HalloVelo
// class version 52.0 (52)
// access flags 0x21
public class $line31/$read$$iw$HalloVelo {

  // compiled from: <console>

  ATTRIBUTE Scala : unknown

  ATTRIBUTE ScalaInlineInfo : unknown
  // access flags 0x1
  public INNERCLASS $line31/$read$$iw $line31/$read $iw
  // access flags 0x1
  public INNERCLASS $line31/$read$$iw$HalloVelo $line31/$read$$iw HalloVelo

  // access flags 0x1011
  public final synthetic L$line31/$read$$iw; $outer

  // access flags 0x1001
  public synthetic $line31$$read$$iw$HalloVelo$$$outer()L$line31/$read$$iw;
   L0
    LINENUMBER 1 L0
    ALOAD 0
    GETFIELD $line31/$read$$iw$HalloVelo.$outer : L$line31/$read$$iw;
    ARETURN
   L1
    LOCALVARIABLE this L$line31/$read$$iw$HalloVelo; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public <init>(L$line31/$read$$iw;)V
    // parameter final synthetic  $outer
   L0
    LINENUMBER 1 L0
    ALOAD 1
    IFNONNULL L1
    ACONST_NULL
    ATHROW
   L1
   FRAME SAME
    ALOAD 0
    ALOAD 1
    PUTFIELD $line31/$read$$iw$HalloVelo.$outer : L$line31/$read$$iw;
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L2
    LOCALVARIABLE this L$line31/$read$$iw$HalloVelo; L0 L2 0
    LOCALVARIABLE $outer L$line31/$read$$iw; L0 L2 1
    MAXSTACK = 2
    MAXLOCALS = 2
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions