I'm writing custom class loader which scans all classes within a .jar file. I would like to make some changes to certain classes based on the current super class they extend. However, the problem is that certain super classes might not have been yet loaded by this class loader or be available in the ClassPool. Is there any way I can obtain superclass name (string value would be enough for me)?
private Class<?> find(String name) throws Exception {
// pre-scanned class entries
// private final Map<String, JarEntry> classByName;
JarEntry classEntry = classByName.get(name);
if (classEntry == null) {
throw new ClassNotFoundException("Unable to find class: " + name);
}
try (JarFile file = new JarFile(filePath)) {
try (DataInputStream classInputStream = new DataInputStream(file.getInputStream(classEntry))) {
ClassFile classFile = new ClassFile(classInputStream);
CtClass clazz = pool.makeClass(classFile);
// this will throw exception if the super class is not yet available
if (clazz.getSuperclass().getName().equals("java.lang.Thread")) {
// make some changes
}
return clazz.toClass(this, null);
}
}
}
Caused by: javassist.NotFoundException: i
at javassist.ClassPool.get(ClassPool.java:422)
at javassist.CtClassType.getSuperclass(CtClassType.java:816)
ClassFile constant pool contains all class names, but I don't know how to pinpoint which one is the superclass. Do I have to put all the classes to the ClassPool beforehand?
Javassist version is 3.25.0-GA
I'm not sure what Javassist's API looks like, but at the bytecode level, there's a super
field in classfile structure which is an index to the constant pool. So you just need to read that field and look at the corresponding class entry in the constant pool to get the superclass name.