javaagent机制,也叫Instrumentation,对应JDK源码的java.lang.instrument包。这是在JDK5之后提供的新特性,开发者能够使用这种机制,实现很多有用的功能,比如计算java对象占用的内存大小,实现class文件的热替换等。这里不做过多解释,主要是我自己才刚接触,也不懂。可以参考http://blog.csdn.net/qyongkang/article/details/7799603这篇博客学习下。这里主要讲下,我自己写代码时候遇到的ClassNotFoundException,搞了好久才解决,无比蛋疼。
事情是这样的,我写了一个用来获取Instrumentation类实例的代理类,源码如下:
package net.aty.size; import java.lang.instrument.Instrumentation; public class GetSizeAgent { private static volatile Instrumentation globalInstr; public static void premain(String args, Instrumentation inst) { System.out.println("agent run.args=" + args); globalInstr = inst; } public static Instrumentation getInstrumentation() { return globalInstr; } }
然后在测试工程下,调用Instrumentation.getObjectSize()计算对象占用的内存大小,源码如下:
public static void main(String[] args) { Instrumentation instr = GetSizeAgent.getInstrumentation(); System.out.println(instr.getObjectSize(new Integer(100))); }
之后需要将GetSizeAgent打成jar包,并编写MANIFEST.MF文件,内容如下
Manifest-Version: 1.0 Premain-Class: net.aty.size.GetSizeAgent Can-Redefine-Classes: true
然后运行test程序,启动的时候指定代理jar包:
但是运行测试程序的时候,报了以下错误
java.lang.ClassNotFoundException: net.aty.size.GetSizeAgent FATAL ERROR in native method: processing of -javaagent failed
类的全路径后面多了个空格,导致加载代理类的时候报了ClassNotFoundException。实在是觉得很诧异,一般我们在编写代码的时候,都习惯使用StringUtils.trim()类似的方法,清除字符串的前后空格。后面上网查了一下,java对MANIFEST.MF文件格式是有规范的,如果不小心违反了,就会报错。
大家可以看下java官网的规范:
--jar文件的Manifest规范
http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html
http://docs.oracle.com/javase/1.5.0/docs/guide/jar/jar.html
http://pages.cs.wisc.edu/~erozner/jdoc/docs/guide/jar/jar.html
http://blog.csdn.net/xiaogugood/article/details/10524183
和http://www.2cto.com/kf/201305/208332.html