快速业务通道

用Java Instrumentation在类加载时添加记录 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-18
om.runjva.instrumentation.LoggerAgent 示例代理

本节列出一个名为 com.runjva.instrumentation.LoggerAgent 示例代理。它操作 java.lang.instrument.ClassFileTransformer 接口并提供所需的 premain(...) 方法。

位于 transform(...) 方法中的实际字节代码操作通过 JBoss "Javassist" 库来实现。这个库提供一个 Java 片断编译器和高级字节代码操作例程。这个编译器允许我们通过创建 Java 字符串片断并编译然后插入到合适的位置进行操作。

签名抽取和返回值字节抽取方法是相当复杂的,并已经被放置在 com.runjva.instrumentation.JavassistHelper 内。它虽然没有列出但在示例代码 .zip 文件中可用。

参阅 参考资料 示例代码部分并链接到 Javassist 和相关背景文章。

用Java Instrumentation在类加载时添加记录(3)

时间:2011-03-05

这是 com.runjva.instrumentation.LoggerAgent 类:

package com.runjva.instrumentation; import java.lang.instrument.*; import java.util.*; import javassist.*; public class LoggerAgent implements ClassFileTransformer {     public static void premain(String agentArgument,        Instrumentation instrumentation) {     if (agentArgument != null) {       String[] args = agentArgument.split(",");       Set argSet = new HashSet(Arrays.asList(args));       if (argSet.contains("time")) {           System.out.println("Start at " + new Date());          Runtime.getRuntime().addShutdownHook(new Thread() {            public void run() {              System.out.println("Stop at " + new Date());              }          });        }     // ... more agent option handling here    } instrumentation.addTransformer(new LoggerAgent()); }

premain(...) 作为类转换器用来添加 LoggerAgent。它也将字符串参数看作一个逗号分隔的选项列表。如果给出选项 time,则将在此时或停机时打印出日期。

String def = "private static java.util.logging.Logger _log;";   String ifLog = "if (_log.isLoggable(java.util.logging.Level.INFO))";   String[] ignore = new String[] { "sun/", "java/", "javax/" };   public byte[] transform(ClassLoader loader, String className,        Class clazz, java.security.ProtectionDomain domain,        byte[] bytes) {    for (int i = 0; i < ignore.length; i++) {         if (className.startsWith(ignore[i])) {            return bytes;         }      }        return doClass(className, clazz, bytes); }

用Java Instrumentation在类加载时添加记录(4)

时间:2011-03-05

transform(...) 方法在示例化为实际对象前由系统类加载器加载的每个类调用。每个类都包含载入这些类所需要的代码,避免了对运行时库类添加记录器。需要查看类名称,并返回未修改的库类(注意:分隔符为斜线而不是点)。

private byte[] doClass(String name, Class clazz, byte[] b) {        ClassPool pool = ClassPool.getDefault();        CtClass cl = 

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号