Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
July 11, 2003
If I have an instance of class X, how can I figure out its classfile location at runtime?
Before I give my answer, I want to point out that your life with Java will be much easier if you get into the habit of writing
strictly disk location-independent code. Load resources such as property and configuration files via Class.getResource() and ResourceBundle.getBundle() as much as possible and avoid java.util.File until absolutely necessary. Not only is this very Java 2 Platform, Enterprise Edition (J2EE)-friendly, you will be surprised
how much you can load from the classpath and how convenient it is.
Having said that, it is occasionally helpful during application testing and debugging to track down classes to their archives. With this kind of usage in mind, I think the following helper method provides the best possible answer within the current Java 2 Platform, Standard Edition (J2SE) APIs:
/**
* Given a Class object, attempts to find its .class location [returns null
* if no such definition can be found]. 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: cls");
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;
}
Your best initial shot is to get the class's CodeSource and its location URL from the class's ProtectionDomain. However, note that even though Class.getProtectionDomain() is likely to return something non-null, there is no guarantee that the result maps to a valid non-null code source location
URL (hence the various guards against null in the code above).
The details depend on the classloader's behavior that loads and defines the class in question. The necessary class and protection
domain association is established by using the five-parameter version of java.lang.ClassLoader.defineClass() with a non-null value for the ProtectionDomain parameter. Normally, this happens for any java.net.URLClassLoader extension, but is not automatically guaranteed for any custom classloader implementation.
Archived Discussions (Read only)