outputstream插装:从write方法读取字节数组

r6l8ljro  于 2021-07-07  发布在  Java
关注(0)|答案(1)|浏览(366)

对于一个监控项目,我尝试使用仪器 OutputStream 使用javassist初始化。我想做一个
OutputStream write() 方法打印什么 byte[] 是给它的(编码是一个不同的问题,在这里并不重要)。我的问题是 OutputStream 在运行时使用代理初始化会使jvm崩溃。使用javassit仅仅操纵字节码失败了 ClassPool.get("java.io.OutputStream") 还会使jvm崩溃。
那班人是不是很难碰?同样的方法也适用于 URI 班级。
有没有其他方法来做我想做的事情,或者是我唯一的选择来替换jre中的rt.jar?

@Override
public byte[] transform(ClassLoader loader, String className,
        Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
        byte[] classfileBuffer) {
        ClassPool pool = ClassPool.getDefault();
        try {
            CtClass cc = pool.get("java.io.OutputStream");
            CtMethod method =
                    Arrays.stream(cc.getDeclaredMethods()).filter(ctMethod -> ctMethod.getLongName().equals("java.io.OutputStream.write(byte[],int,int)"))
                            .findFirst().get();
            method.insertBefore("System.out.println(new String($1, java.nio.charset.StandardCharsets.UTF_8));");
            return cc.toBytecode();
        } catch (NotFoundException | CannotCompileException | IOException e) {
            e.printStackTrace();
        }
    return null;
}

生成输出:
线程“main”java.lang.noclassdeffounderror中出现异常:org/springframework/boot/springapplication(错误名称:java/io/outputstream)
因为我用“new”覆盖了第一个加载的类 OutputStream 已经有了。这个 OutputStream 但是,类永远不会被调用到转换方法中。。。

6yt4nkrj

6yt4nkrj1#

这个 transform 方法是一个回调函数,可以为每个加载的类调用它。您将在 className 参数和中的原始定义 classfileBuffer .
因此,首先要做的是检查当前调用是否真的对应于要转换的类。如果没有,就回来 null . 不执行此操作,但返回 java.io.OutputStream 不管请求您转换哪个类。所以你才会出错。你被要求改变班级 org/springframework/boot/SpringApplication 但是返回一个名为 java/io/OutputStream . 注意消息中的“错误名称”。当然,如果没有名称验证,这个不匹配的类将导致更多的问题。
在检查当前调用是否负责 java.io.OutputStream ,您应该使用提供的 classfileBuffer 用于阅读原始类版本,而不是使用 ClassPool.getDefault().get(…) ,作为 ClassPool 不知道您在参数中收到的类的版本,可能会找到错误的版本,或者无法访问类al all。
但是请注意,检测方法 OutputStream.write(byte[],int,int) 光靠自己是不够的。正如其文件所说:
鼓励子类重写此方法并提供更有效的实现。
在所有相关的实现类中都会发生这种情况。要记录重写方法的调用,还必须对它们进行检测。还要注意,子类可以重写 write(byte[]) 不委托给 write(byte[],int,int) .

相关问题