JDK-6431936 : (cl) Suggest public URL java.lang.Class.getLocation()
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:class_loading
  • Affected Version: 5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: linux
  • CPU: x86
  • Submitted: 2006-05-30
  • Updated: 2017-08-30
  • Resolved: 2017-08-30
Related Reports
Relates :  
Description
It seems that many Java developers are unaware there is any way to find out where a given java.lang.Class object was loaded from. This seems to be desired pretty often when debugging "ClassLoader hell".

In fact it is quite easy to do it once you know how. But it is not easy to find out how. You need to use a ProtectionDomain, which is in java.security.* and so doesn't sound like it should have anything to do with this problem. So discoverability is poor.

Comments
java.lang.module.ModuleReference::location method returns the location of named module. Classes on module path can use the new API to get the location. For classpath, CodeSource is present and suggest to continue using that instead of introducing a new API.
29-08-2017

SUGGESTED FIX Suggest addition to java.lang.Class: /** * Gets the location from which this class object was probably defined. * The accuracy of this method relies on two assumptions: * <ol> * <li>The class loader which defined this class used * {@link ClassLoader#defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain)} * so as to associate a {@link ProtectionDomain} with the class. * <li>The class loader actually read this class' definitions from * a class file at that location (rather than, say, constructing a definition * on the fly). * </ol> * @return a URL from which this class' definition may have been read, or null if unknown */ public URL getLocation() { CodeSource cs = getProtectionDomain().getCodeSource(); if (cs != null) { String resource = getName().replace('.', '/') + ".class"; URL location = cs.getLocation(); if (location.getPath().endsWith("/")) { return new URL(location, resource); } } return null; } Would need to take care to make sure that URLClassLoader, if passed a bogus JAR URL such as file:/tmp/foo.jar nonetheless is defining the CodeSource with the correct location, i.e. jar:file:/tmp/foo.jar!/ since you want a usable URL such as jar:file:/tmp/foo.jar!/p/C.class rather than the quite incorrect file:/tmp/p/C.class (the above code will in fact return null rather than the incorrect URL).
30-05-2006