1. 程式人生 > >使用JDK的javaagent機制時候,遇到的蛋疼無比的ClassNotFoundException

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



但是執行測試程式的時候,報了以下錯誤

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