<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks

    #

    當你要調(diào)試一個程序時,如果能把你的Java代碼注入到目標程序并運行,這可能會給你的調(diào)試開發(fā)帶來很大的方便,比如打印出一些全局變量值,屬性等。
    本人出于興趣,封裝了一個簡單的Java庫,可以達到這個目的。

    這個庫主要的API如下

    1 public ? class ?com.yovn.labs.vmattach.VMTool
    2 {
    3 ????? public ? static ? void ?attachJarToVM(String?pid,String?jarPath,String?mainClassToRun) throws ???AttachException
    4
    5 }

    第一個參數(shù): 你要注入的Java程序的PID
    第二個參數(shù): 你要把那個jar文件(最好用路徑全名)注入到目標程序
    第三個參數(shù): 注入目標程序后運行你指定的那個Class(全名)

    該庫可以從這里下載:http://www.tkk7.com/Files/javacap/VMAttach.zip

    具體有什么用呢?這個看使用者怎么用,下面我弄個簡單的例子。
    加入一個程序使用一些Singleton對象,并且已經(jīng)部署并運行了,現(xiàn)在我可能要查看一下這個Singleton對象的一些內(nèi)部狀態(tài)。

    比如,這個程序如下:

    ?1 package ?test;?
    ?2
    ?3 import ?java.util.Random;?
    ?4
    ?5 /**
    ?6 ?*? @author ?yovn
    ?7 ?*
    ?8 ? */

    ?9 public ? class ?UseSingletonApp? {?
    10
    11 ? /**
    12 ??*? @param ?args
    13 ?? */

    14 ? public ? static ? void ?main(String[]?args)? {
    15 ??
    16 ?? new ?Thread(Singleton.getInstance()).start();
    17 ???
    18
    19 ?}

    20 ? public ? static ? class ?Singleton? implements ?Runnable
    21 ? {
    22 ?? private ? final ? static ?Singleton?instance = new ?Singleton();
    23 ?? private ? volatile ? int ?stateNum;
    24 ??
    25 ??
    26 ?? private ?Singleton()
    27 ?? {
    28 ???
    29 ??}

    30 ?? public ? static ?Singleton?getInstance()
    31 ?? {
    32 ??? return ?instance;
    33 ??}

    34 ?? public ? void ?run()? {
    35 ??? while ( true )
    36 ??? {
    37 ????stateNum = new ?Random().nextInt();
    38 ???? try ? {
    39 ?????Thread.sleep( 1000 );
    40 ????}
    ? catch ?(InterruptedException?e)? {
    41 ????? // ?TODO?Auto-generated?catch?block
    42 ?????e.printStackTrace();
    43 ????}

    44 ???}

    45 ???
    46 ??}

    47 ??
    48 ?}
    ?
    49
    50 }

    51
    52


    現(xiàn)在啟動這個Java程序,在命令行窗口運行tasklist查看它的PID,假如為3020。
    現(xiàn)在加入我要知道這個程序現(xiàn)在的Singleton 對象的stateNum值為多少,該怎么辦呢?
    我們以前一般要以debug模式啟動,然后查看變量,難道正常啟動就沒辦法了?
    當然有,我們可以寫個程序,注入到目標進程然后打印出來,不就OK.

    當然,這里有個問題,注入的java程序是單獨在一個線程里跑的,它的Context Class Loader是沒有設置的,你要采取一些措施才能找到目標進程已經(jīng)載入的class,請看下面的代碼:

    ?1?package?test;?
    ?2?
    ?3?import?java.lang.reflect.Field;
    ?4?import?java.lang.reflect.Method;?
    ?5?
    ?6?/**
    ?7??*?@author?yovn
    ?8??*
    ?9??*/
    10?public?class?AttachDemo?{?
    11?
    12??/**
    13???*?@param?args
    14???*/
    15??public?static?void?main(String[]?args)?{
    16???try?{
    17????Class?cls=null;//the?class?we?try?to?load?that?alrady?loaded?by?target?process
    18????
    19????//following?code?iterate?the?thread?tree,to?use?every?one?context?class?loader?to?load?the?class?util?success
    20????ThreadGroup?group?=?Thread.currentThread().getThreadGroup();
    21????while?(group?!=?null)?{
    22?????int?tc?=?group.activeCount();
    23?????Thread[]?ts?=?new?Thread[tc];
    24?????group.enumerate(ts);
    25?????for?(int?i?=?0;?i?<?tc;?i++)?{
    26??????if?(ts[i]?!=?null)?{
    27???????try{
    28????????cls=ts[i].getContextClassLoader().loadClass("test.UseSingletonApp$Singleton");
    29???????Thread.currentThread().setContextClassLoader(ts[i].getContextClassLoader());
    30???????break;
    31???????}catch(Exception?e){}
    32???????
    33??????}
    34?????}
    35?????group?=?group.getParent();
    36????}
    37????if(cls==null)
    38????{
    39?????System.out.println("can?not?load?class");
    40?????return;
    41????}
    42????Field?f?=?cls.getDeclaredField("stateNum");
    43????f.setAccessible(true);
    44????Method?getInM?=?cls.getMethod("getInstance",?new?Class[]?{});
    45????Object?singleton?=?getInM.invoke(null,?new?Object[]?{});//get?the?singleton?object
    46????
    47????int?stateNum?=?((Integer)?f.get(singleton)).intValue();
    48????System.out.println("Singleton's?stateNum?currently?is?:"?+?stateNum);
    49???}?catch?(Exception?e)?{
    50????e.printStackTrace();
    51???}?
    52?
    53??}?
    54?
    55?}
    56?
    57?


    現(xiàn)在,你需要把test.AttachDemo類編譯好,單獨打包到一個 jar文件,比如d:盤的attachdemo.jar里。
    上面準備好了,你就差注入attachdemo.jar到目標進程3020了,
    如下代碼就可以完成注入:

    ?1?import?com.yovn.labs.vmattach.AttachException;
    ?2?import?com.yovn.labs.vmattach.VMTool;?
    ?3?
    ?4?public?class?Test?{
    ?5?/**
    ?6???*?@param?args
    ?7???*?@throws?AttachException?
    ?8???*/
    ?9??public?static?void?main(String[]?args)?throws?AttachException?{
    10???VMTool.attachJarToVM("3020",?"D:\\attachdemo.jar",?"test.AttachDemo");
    11??}?
    12?
    13?}
    14?
    15?



    運氣不錯的話,你就能在運行UseSingletonApp程序的命令窗口輸出類似:
    Singleton's stateNum currently is :1630285997



    總結(jié):
    目前還不是很完善,只能attach一次,稍后我會完善這個功能。另外就是只支持Window 2000/NT/XP/2003 ,Windows98不支持,Linux/Unix也是還不支持的。

    posted @ 2007-01-04 13:52 DoubleH 閱讀(6166) | 評論 (4)編輯 收藏

    僅列出標題
    共5頁: 上一頁 1 2 3 4 5 
    主站蜘蛛池模板: 99久久99这里只有免费的精品| 精品国产亚洲第一区二区三区| 久久免费美女视频| 国产午夜亚洲不卡| 中文在线免费不卡视频| 亚洲Av无码国产情品久久| 国产成人精品亚洲| 国产精品亚洲αv天堂无码| 精品国产免费一区二区三区| 亚洲精品无码永久中文字幕| 成全视频免费观看在线看| 无码欧精品亚洲日韩一区| 无码人妻丰满熟妇区免费| 亚洲精品91在线| 毛片A级毛片免费播放| 亚洲AV无码AV日韩AV网站| 亚洲AⅤ视频一区二区三区| 一区二区三区免费高清视频| 国产亚洲精品精华液| 国产福利视精品永久免费| 亚洲日本人成中文字幕| 国产jizzjizz视频免费看| 一个人看的免费视频www在线高清动漫| 在线播放亚洲第一字幕| 免费看又黄又无码的网站| 国产亚洲福利在线视频| 免费观看午夜在线欧差毛片| 久久不见久久见免费影院www日本| 亚洲av不卡一区二区三区| 男男AV纯肉无码免费播放无码| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲天天做日日做天天看 | 精品久久久久亚洲| 亚洲精品国产字幕久久不卡| 最近2019年免费中文字幕高清| 亚洲中文字幕久久精品无码VA | 午夜免费啪视频在线观看| 精品亚洲AV无码一区二区三区| 免费大片在线观看网站| 毛片在线播放免费观看| 亚洲AV无码一区二区一二区|