Better jdb integration


Recently I have had to debug our server with jdb.
I could not use remote debug or sdb(it require sources on target machine) for security reason.

The most difficult task was to set correct breakpoint( `stop at class_id:line’ ). It was a real challenge for me, to find out anonymous classes and its source lines with javap :)))

So I have done simple utility which allow to do something like:

>jdb -attach jdbconn
>stop in$.main
>eval java.lang.Class.forName("ru.bitec.Jdb")
>print ru.bitec.Jdb.parseClasses("Example")

print ru.bitec.Jdb.parseClasses("Example")
 ru.bitec.Jdb.parseClasses("Example") = "

>stop at$$anon$1:14

I think it will be greate if such helper exists in a standard scala package.

I used asm to do it:

  def parseClasses(name:String):mutable.HashMap[String,
    mutable.HashMap[Int,mutable.Set[String]]] = {
    val classLoader = this.getClass.getClassLoader
    val stringBuilder = StringBuilder.newBuilder
    val s = new Reflections(
      ClasspathHelper.forPackage("some.root"),new ResourcesScanner()
    val map = mutable.HashMap.empty[String,
    for(c <-s; s <- managed(classLoader.getResourceAsStream(c))){
      val reader = new ClassReader(s)
        new ClassVisitor(Opcodes.ASM7) {
          var source:String = _
          override def visitSource(source: String, debug: String): Unit = {
            this.source = source
            super.visitSource(source, debug)
          override def visitMethod(access: Int, name: String, descriptor: String, signature: String, exceptions: Array[String]): MethodVisitor = {
            new MethodVisitor(Opcodes.ASM7) {
              override def visitLineNumber(line: Int, start: Label): Unit = {
                val lineMap = map(source)
                val classSet = lineMap.getOrElseUpdate(line, mutable.Set.empty[String])
                super.visitLineNumber(line, start)
        }, 0)