Explain Codes LogoExplain Codes Logo

Determine which JAR file a class is from

java
class-loading
java-8
reflection
Nikita BarsukovbyNikita Barsukov·Nov 1, 2024
TLDR

To swiftly identify the source JAR of a class:

String path = MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();

This line of code pinpoints the location where MyClass took its first breath, leading you straight to its JAR residence.

Survival guide for bootstrap classes

When trying to retrieve the JAR location of core Java classes loaded by the bootstrap classloader, such as java.lang.String, the getProtectionDomain() method isn't helpful as it returns null. In these cases, good old manual search or other tooling might be all you have.

Packing for diverse environments

In intricate applications, classes may be sourced from non-conventional locations: over http, from a nested JAR, or via custom class loaders. The simplistic getCodeSource() routine might fall short here. findPathJar() from Lombok Patcher's LiveInjector can be a lifeline for these scenarios.

A peek inside the JAR

Unearth the secrets held within a JAR file or identify if a particular class resides within, using command-line magic:

# Meet all the JAR's inhabitants unzip -l path/to/file.jar # Uncover the hiding place of the elusive class within JAR files around you. find . -name "*.jar" -exec sh -c 'unzip -l "${1}" | grep -H --label "${1}" YourClass.class' _ {} \;

All-purpose code for diverse paths

Here's an enhanced approach, much like a Swiss Army Knife, for any environment:

public String locateClass(Class<?> clazz) { try { CodeSource cs = clazz.getProtectionDomain().getCodeSource(); if (cs != null) { URL url = cs.getLocation(); return new File(url.toURI()).getAbsolutePath(); // Voila! Here's the path. At least, most of the time... } } catch (URISyntaxException e) { return "Something's off with the path: " + e.getMessage(); } throw new UnsupportedOperationException("The classloader's got stage fright"); }

This approach caters to URI syntax exceptions and handles cases where the class loader turns shy.

Running a shell game for class hunters

You can automate your search for the elusive class hiding in some JAR file, with this handy shell script (findclass.sh):

#!/bin/sh CLASSNAME=$(echo "$1" | tr '.' '/') for jar in $(find . -name "*.jar") do if unzip -l "$jar" | grep -q "$CLASSNAME.class"; then echo "Eureka! 'Found in: $jar" fi done

Supply the fully-qualified class name as a parameter, and the script will shake the bushes.

Conquering prodigious class packaging

Sometimes classes are packaged or nested in ways only a mad scientist could appreciate. Our conventional tools might feel a bit lost here.

Unpacking the Matryoshka

Nested classes stored in a JAR within a JAR scenario can leave traditional tools scratching their heads. Apache Commons Compress rolls up its sleeves for these nested archives.

Far-flung class loading

Distributed applications might fetch classes from a distant location. Here, getProtectionDomain().getCodeSource().getLocation() will usually return a URL looking something like http, https, or a variant depending on the tech stack.

Juggling dynamic classes

Modern frameworks and containers love to juggle dynamic classes, which can mystify your quest for class location discovery. Dynamic proxies won't be found lounging in a JAR, as they're whipped up on the go.