java - 使用 javassist 从 jar 中解析类

标签 java 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)));
}

最佳答案

您可以通过以下代码从 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 检测的类需要添加到类路径中。

您可能会看看我如何在插件用例中使用它们:

HTH

关于java - 使用 javassist 从 jar 中解析类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26381109/

相关文章:

java - JSF 2 用户界面 :repeat: group every n items inside a div

java - 通过命令行编译但不是在 ant 中

java - 使用@JsonAnySetter 映射jackson 返回带有javassist 类的Unrecognized 字段

java - 在运行时增强 java 对象

java - 如何在 Log4j2 中将 appender 添加到 Logger

java - 写入从 getResourceAsStream() 返回的文件流

java - 使用 Javassist 读取变量的值

compilation - javassist编译错误没有这样的类

java - 如何使用 javassist 更改字段的初始值

java - 将字符串转换为整数 JSP