content: package sun.jvm.hotspot.tools;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Comparator;
  
  import sun.jvm.hotspot.debugger.AddressException;
  import sun.jvm.hotspot.memory.SystemDictionary;
  import sun.jvm.hotspot.oops.InstanceKlass;
  import sun.jvm.hotspot.oops.Klass;
  import sun.jvm.hotspot.oops.Oop;
  import sun.jvm.hotspot.oops.OopField;
  import sun.jvm.hotspot.oops.OopUtilities;
  import sun.jvm.hotspot.runtime.VM;
  
  public class TBDumpClassURL extends Tool {
      public void run() {
          try {
              final ArrayList<InstanceKlass> klasses = new ArrayList<InstanceKlass>(128);
  
              SystemDictionary dict = VM.getVM().getSystemDictionary();
              dict.classesDo(new SystemDictionary.ClassVisitor() {
                  public void visit(Klass k) {
                      if (k instanceof InstanceKlass) {
                          klasses.add((InstanceKlass) k);
                      }
                  }
              });
  
              Collections.sort(klasses, new Comparator<InstanceKlass>() {
                  public int compare(InstanceKlass x, InstanceKlass y) {
                      return x.getName().asString().compareTo(y.getName().asString());
                  }
              });
  
              System.out.println("#class              #path               #loader");
              System.out.println("-----------------------------------------------");
              for (InstanceKlass k : klasses) {
                  System.out.printf("%s, %s, %s\n", getClassNameFrom(k), getPathFromInstanceKlass(k),
                          getClassLoaderOopFrom(k));
              }
          } catch (AddressException e) {
              System.err.println("Error accessing address 0x" + Long.toHexString(e.getAddress()));
              e.printStackTrace();
          }
      }
  
      private static String getClassNameFrom(InstanceKlass klass) {
          return klass != null ? klass.getName().asString().replace('/', '.') : null;
      }
  
      private static String getPathFromInstanceKlass(InstanceKlass klass) {
          Oop protectionDomain = klass.getProtectionDomain();
          if (protectionDomain == null)
              return null;
  
          Oop codesource = getOopFieldValueFrom(protectionDomain, "codesource", "Ljava/security/CodeSource;");
          if (codesource == null)
              return null;
  
          Oop location = getOopFieldValueFrom(codesource, "location", "Ljava/net/URL;");
          if (location == null)
              return null;
  
          Oop path = getOopFieldValueFrom(location, "path", "Ljava/lang/String;");
          if (path == null)
              return null;
  
          return OopUtilities.stringOopToString(path);
      }
  
      private static String getClassLoaderOopFrom(InstanceKlass klass) {
          Oop loader = klass.getClassLoader();
          return loader != null ? getClassNameFrom((InstanceKlass) loader.getKlass()) + " @ " + loader.getHandle()
                  : "<bootstrap>";
      }
  
      private static Oop getOopFieldValueFrom(Oop oop, String name, String sig) {
          InstanceKlass klass = (InstanceKlass) oop.getKlass();
          OopField field = (OopField) klass.findField(name, sig);
          return field.getValue(oop);
      }
  
      public String getName() {
          return "TBDumpClassURL";
      }
  
      public static void main(String[] args) {
          TBDumpClassURL tool = new TBDumpClassURL();
          tool.start(args);
          tool.stop();
      }
  }
  