Find a class’s runtime origin

JavaWorld has a great article on finding a class’s runtime origin called Back to your Class roots. Below is the highly useful getClassLocation method from the article.

/**
 * Given a Class object, attempts to find its .class location.
 * Use for testing/debugging only.
 * 
 * @return URL that points to the class definition; null if not found
 */
public static URL getClassLocation (final Class cls) {
  if (cls == null) throw new IllegalArgumentException ("null input");
  
  URL result = null;
  final String clsAsResource = cls.getName ().replace ('.', '/').concat (".class");
  
  final ProtectionDomain pd = cls.getProtectionDomain ();
  // java.lang.Class contract does not specify if 'pd' can ever be
  // null; it is not the case for Sun's implementations, but guard
  // against null just in case:
  if (pd != null) {
    final CodeSource cs = pd.getCodeSource ();
    // 'cs' can be null depending on the classloader behavior:
    if (cs != null) result = cs.getLocation ();
    
    if (result != null) {
      // Convert a code source location into a full class file location
      // for some common cases:
      if ("file".equals (result.getProtocol ())) {
        try {
          if (result.toExternalForm ().endsWith (".jar") ||
            result.toExternalForm ().endsWith (".zip")) 
            result = new URL ("jar:".concat (result.toExternalForm ())
              .concat("!/").concat (clsAsResource));
          else if (new File (result.getFile ()).isDirectory ())
            result = new URL (result, clsAsResource);
        }
        catch (MalformedURLException ignore) {}
      }
    }
  }
  
  if (result == null) {
    // Try to find 'cls' definition as a resource; this is not
    // documented to be legal, but Sun's implementations seem to allow
    // this:
    final ClassLoader clsLoader = cls.getClassLoader ();
    
    result = clsLoader != null ?
      clsLoader.getResource (clsAsResource) :
      ClassLoader.getSystemResource (clsAsResource);
  }
  
  return result;
}

Leave a Reply

Your email address will not be published. Required fields are marked *