Determine which JAR file a class is from Determine which JAR file a class is from java java

Determine which JAR file a class is from


Yes. It works for all classes except classes loaded by bootstrap classloader. The other way to determine is:

Class klass = String.class;URL location = klass.getResource('/' + klass.getName().replace('.', '/') + ".class");

As notnoop pointed out klass.getResource() method returns the location of the class file itself. For example:

jar:file:/jdk/jre/lib/rt.jar!/java/lang/String.classfile:/projects/classes/pkg/MyClass$1.class

The getProtectionDomain().getCodeSource().getLocation() method returns the location of the jar file or CLASSPATH

file:/Users/home/java/libs/ejb3-persistence-1.0.2.GA.jarfile:/projects/classes


Checkout the LiveInjector.findPathJar() from Lombok Patcher LiveInjector.java. Note that it special cases where the file doesn't actually live in a jar, and you might want to change that.

/** * If the provided class has been loaded from a jar file that is on the local file system, will find the absolute path to that jar file. *  * @param context The jar file that contained the class file that represents this class will be found. Specify {@code null} to let {@code LiveInjector} *                find its own jar. * @throws IllegalStateException If the specified class was loaded from a directory or in some other way (such as via HTTP, from a database, or some *                               other custom classloading device). */public static String findPathJar(Class<?> context) throws IllegalStateException {    if (context == null) context = LiveInjector.class;    String rawName = context.getName();    String classFileName;    /* rawName is something like package.name.ContainingClass$ClassName. We need to turn this into ContainingClass$ClassName.class. */ {        int idx = rawName.lastIndexOf('.');        classFileName = (idx == -1 ? rawName : rawName.substring(idx+1)) + ".class";    }    String uri = context.getResource(classFileName).toString();    if (uri.startsWith("file:")) throw new IllegalStateException("This class has been loaded from a directory and not from a jar file.");    if (!uri.startsWith("jar:file:")) {        int idx = uri.indexOf(':');        String protocol = idx == -1 ? "(unknown)" : uri.substring(0, idx);        throw new IllegalStateException("This class has been loaded remotely via the " + protocol +                " protocol. Only loading from a jar on the local file system is supported.");    }    int idx = uri.indexOf('!');    //As far as I know, the if statement below can't ever trigger, so it's more of a sanity check thing.    if (idx == -1) throw new IllegalStateException("You appear to have loaded this class from a local jar file, but I can't make sense of the URL!");    try {        String fileName = URLDecoder.decode(uri.substring("jar:file:".length(), idx), Charset.defaultCharset().name());        return new File(fileName).getAbsolutePath();    } catch (UnsupportedEncodingException e) {        throw new InternalError("default charset doesn't exist. Your VM is borked.");    }}


Use

String path = <Any of your class within the jar>.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 

If this contains multiple entries then do some substring operation.