Разобрать классы из jar с помощью javassist

Я нуб в javassist. Кто-нибудь может дать образец, как загружать классы из jar и сохранять их с помощью javassist?

jar = new JarFile(fileName);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) entries.nextElement();
if(jarEntry == null)
    break;
if(jarEntry.getName().endsWith(".class")) {
    // ??????
} else {
    resources.add(new RResource(jarEntry.getName(), jar.getInputStream(jarEntry)));
}

person MG_REX    schedule 15.10.2014    source источник


Ответы (1)


Вы можете загрузить байты из соответствующего класса внутри файла JAR с помощью кода ниже:

JarFile jarFile = new JarFile(file);
// lets get a reference to the .class-file contained in the JAR
ZipEntry zipEntry = jarFile.getEntry(className.replace(".", "/")+".class");
if (zipEntry == null) {
    jarFile.close();
    return null;
}
// with our valid reference, we are now able to get the bytes out of the jar-archive
InputStream fis = jarFile.getInputStream(zipEntry);
byte[] classBytes = new byte[fis.available()];
fis.read(classBytes);

Чтобы загрузить байты в javassist, вы можете сделать следующее:

ClassPool cp = ClassPool.getDefault();
cp.insertClassPath(new ClassClassPath(this.getClass()));
ClassPath cp1 = null;
ClassPath cp2 = null;

// add the JAR file to the classpath
try {
    cp1 = cp.insertClassPath(jarFile.getAbsolutePath());
} catch (NotFoundException e1) {
    e1.printStackTrace();
    return null;
}
// add the class file we are going to modify to the classpath
cp2 = cp.appendClassPath(new ByteArrayClassPath(className, classBytes));

byte[] modifiedBytes;
try {
    CtClass cc = cp.get(className);
    // skip instrumentation if the class is frozen and therefore
    // can't be modified
    if (!cc.isFrozen()) {
        // do your javassist stuff here
    }
    modifiedBytes = cc.toBytecode();
} catch (NotFoundException | IOException | CannotCompileException | ClassNotFoundException e) {
    handleException(e);
} finally {
    // free the locked resource files
    cp.removeClassPath(cp1);
    cp.removeClassPath(cp2);
}

// write your modified bytes somewhere
if (modifiedBytes.length > 0) {
    try(FileOutputStream fos = new FileOutputStream("pathname")) {
        fos.write(modifiedBytes);
    }
}

Возможно, часть кода можно сократить, но именно так я загружаю байты из JAR-файла и загружаю их в Javassist. Файл JAR загружается в путь к классам Javassist из-за возможных зависимостей. Также класс, который я использую с Javassist, по какой-то причине нужно было добавить в путь к классам.

Вы можете посмотреть, как я использую их в примере использования плагина:

ХТН

person Roman Vottner    schedule 15.10.2014