使用JDK的javaagent机制时候,遇到的蛋疼无比的ClassNotFoundException

     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包:

使用JDK的javaagent机制时候,遇到的蛋疼无比的ClassNotFoundException_第1张图片

但是运行测试程序的时候,报了以下错误

java.lang.ClassNotFoundException: net.aty.size.GetSizeAgent
FATAL ERROR in native method: processing of -javaagent failed


最终定位的结果是Premain-Class: net.aty.size.GetSizeAgent   

类的全路径后面多了个空格,导致加载代理类的时候报了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

 

你可能感兴趣的:(java高级话题)