import java.lang.reflect.;
import java.util.;
public class ObjectFinderAll {
private static final int MAX_DEPTH = 10;
private static final int MAX_VISITED = 200_000;
private final Set<Object> visited = Collections.newSetFromMap(new IdentityHashMap<>());
private final Set<Class<?>> loadedClasses = new HashSet<>();
private final List<Object> matches = new ArrayList<>();
private final Class<?> targetClass;
public ObjectFinderAll(Class<?> targetClass) {
this.targetClass = targetClass;
}
public List<Object> findAllInstances() {
Queue<Object> queue = new ArrayDeque<>();
collectStatics(queue);
collectThreadLocals(queue);
int steps = 0;
while (!queue.isEmpty() && steps < MAX_VISITED) {
Object obj = queue.poll();
steps++;
if (obj == null || visited.contains(obj)) continue;
visited.add(obj);
// Match
if (targetClass.isAssignableFrom(obj.getClass())) {
matches.add(obj);
}
// Explore non-primitive fields
if (shouldExpand(obj.getClass())) {
for (Object child : getFields(obj)) {
if (child != null && !visited.contains(child)) {
queue.add(child);
}
}
}
}
return matches;
}
private void collectStatics(Queue<Object> queue) {
for (Class<?> clazz : getAllReachableClasses()) {
for (Field field : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) continue;
field.setAccessible(true);
try {
Object val = field.get(null);
if (val != null && visited.add(val)) {
queue.add(val);
}
} catch (Throwable ignored) {}
}
}
}
private void collectThreadLocals(Queue<Object> queue) {
for (Thread thread : Thread.getAllStackTraces().keySet()) {
for (Field field : thread.getClass().getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) continue;
field.setAccessible(true);
try {
Object val = field.get(thread);
if (val != null && visited.add(val)) {
queue.add(val);
}
} catch (Throwable ignored) {}
}
}
}
private List<Object> getFields(Object obj) {
List<Object> results = new ArrayList<>();
Class<?> cls = obj.getClass();
while (cls != null) {
for (Field f : cls.getDeclaredFields()) {
if (Modifier.isStatic(f.getModifiers())) continue;
f.setAccessible(true);
try {
Object val = f.get(obj);
if (val != null) results.add(val);
} catch (Throwable ignored) {}
}
cls = cls.getSuperclass();
}
return results;
}
private boolean shouldExpand(Class<?> cls) {
if (cls.isPrimitive() || cls.isEnum()) return false;
String name = cls.getName();
return !(name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("sun.") || name.startsWith("jdk."));
}
private Set<Class<?>> getAllReachableClasses() {
if (!loadedClasses.isEmpty()) return loadedClasses;
for (Thread t : Thread.getAllStackTraces().keySet()) {
for (StackTraceElement elem : t.getStackTrace()) {
try {
Class<?> cls = Class.forName(elem.getClassName());
loadedClasses.add(cls);
} catch (Throwable ignored) {}
}
}
return loadedClasses;
}
// === DEMO ===
public static void main(String[] args) throws Exception {
if (args.length < 1) {
System.err.println("Usage: ObjectFinderAll <fully.qualified.ClassName>");
System.exit(1);
}
Class<?> target = Class.forName(args[0]);
ObjectFinderAll finder = new ObjectFinderAll(target);
List<Object> results = finder.findAllInstances();
System.out.println("==== RESULTS ====");
if (results.isEmpty()) {
System.out.println("❌ No instances of " + target.getName() + " found.");
} else {
System.out.println("✅ Found " + results.size() + " instance(s):");
int i = 1;
for (Object obj : results) {
System.out.println("[" + i++ + "] " + obj.getClass().getName() + " -> " + obj);
dumpObjectFields(obj);
}
}
}
// Simple reflection-based field printer
private static void dumpObjectFields(Object obj) {
if (obj == null) return;
Class<?> cls = obj.getClass();
System.out.println("Fields of: " + cls.getName());
while (cls != null) {
for (Field f : cls.getDeclaredFields()) {
f.setAccessible(true);
try {
Object value = f.get(obj);
System.out.printf(" - %s = %s%n", f.getName(), String.valueOf(value));
} catch (Throwable ignored) {}
}
cls = cls.getSuperclass();
}
System.out.println();
}
}
Top comments (0)