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

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

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

    2010年3月14日

    例子下載在此

    最近搞了個小實驗,發現Eclipse 插件的類加載的一個問題。Eclipse使用Equinox實現OSGi的框架,可以在插件的配置中確定哪些類expose出去,哪些類不能為外部所見。我發現的問題是,可以通過ClassLoader繞過這個限制,在外部插件中加載到插件里那些不為外部所見的類,并且能夠創建類的實例,可以通過反射調用其方法(當然,如果被加載的類實現了某些接口,也可以通過接口的引用直接調用相應的方法)。

    為了演示這個問題,先在eclipse中創建一個插件UtilityLibrary

    其中utilitylibrary.expose包中的類會暴露給外部,而utilitylibrary.hide包中的類不會暴露給外部。在MANIFEST.MF中增加這個設置:


    VisiableClassVisiableClass類的內容很簡單:
    package utilitylibrary.expose;

    public class VisiableClass {
        
    public VisiableClass() {
            System.out.println(
    "This is VisiableClass");
        }

        
    public String getMessage() {
            
    return "From VisiableClass:\r\n"
                    
    + this.getClass().getClassLoader().toString() + "\t";
        }
    }

    package utilitylibrary.hide;

    public class InvisiableClass {
        
    public InvisiableClass() {
            System.out.println(
    "InvisiableClass");
        }

        
    public String getMessage() {
            
    return "From InvisiableClass:\r\n"
                    
    + this.getClass().getClassLoader().toString() + "\t";
        }
    }


    其實主要就是打印出相應的信息。類代碼幾乎是一樣的。

    下面創建另一個插件UsePlugin,依賴并使用UtilityLibrary中的類。插件其實就是Eclipse自帶的Hello World程序,它會在eclipse 的toolbar上增加一個按鈕,點擊后會彈出一個MessageBox。好,MessageBox上顯示的就是從UtilityLibrary中類的方法的返回值。首先增加插件依賴關系:


    在SampleAction中的Run方法里,如果直接使用InvisiableClass,插件完全找不到這個類,修改建議里面建議expose這個類:


    當然,使用VisiableClass是沒問題的。下面通過VisiableClass來將InvisiableClass拽出來,SampleAction類的源代碼如下,只要關心run方法就可以了:

    package useplugin.actions;

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;

    import org.eclipse.jface.action.IAction;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.jface.viewers.ISelection;
    import org.eclipse.ui.IWorkbenchWindow;
    import org.eclipse.ui.IWorkbenchWindowActionDelegate;

    import utilitylibrary.expose.VisiableClass;

    /**
     * Our sample action implements workbench action delegate. The action proxy will
     * be created by the workbench and shown in the UI. When the user tries to use
     * the action, this delegate will be created and execution will be delegated to
     * it.
     * 
     * 
    @see IWorkbenchWindowActionDelegate
     
    */
    public class SampleAction implements IWorkbenchWindowActionDelegate {
        
    private IWorkbenchWindow window;

        
    /**
         * The constructor.
         
    */
        
    public SampleAction() {
        }

        
    /**
         * The action has been activated. The argument of the method represents the
         * 'real' action sitting in the workbench UI.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#run
         
    */
        
    public void run(IAction action) {
            
    try {
                Class
    <?> clazz = VisiableClass.class.getClassLoader().loadClass(
                        
    "utilitylibrary.hide.InvisiableClass");
                Object obj 
    = clazz.newInstance();
                Method method 
    = clazz.getMethod("getMessage");
                Object ret 
    = method.invoke(obj, new Object[] {});
                System.out.println(ret);
                MessageDialog.openInformation(window.getShell(), 
    "UsePlugin", ret
                        .toString());
            } 
    catch (ClassNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (InstantiationException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (IllegalAccessException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (SecurityException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (NoSuchMethodException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (IllegalArgumentException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (InvocationTargetException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        
    /**
         * Selection in the workbench has been changed. We can change the state of
         * the 'real' action here if we want, but this can only happen after the
         * delegate has been created.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#selectionChanged
         
    */
        
    public void selectionChanged(IAction action, ISelection selection) {
        }

        
    /**
         * We can use this method to dispose of any system resources we previously
         * allocated.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#dispose
         
    */
        
    public void dispose() {
        }

        
    /**
         * We will cache window object in order to be able to provide parent shell
         * for the message dialog.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#init
         
    */
        
    public void init(IWorkbenchWindow window) {
            
    this.window = window;
        }
    }


    在run方法里面,直接使用VisiableClass.class.getClassLoader().loadClass("utilitylibrary.hide.InvisiableClass");來加載本不應該被外部所見的Invisiable類。因為在Eclipse中,每個插件使用一個ClassLoader,所以用來加載VisiableClass類的ClassLoader也同樣負責加載在同一個插件中的InvisiableClass類。這樣InvisiableClass就在插件外部被加載成功了。類加載成功后,剩下的事情就是順水推舟了,創建個實例然后使用反射調用相應的方法。
    程序運行的時候,點擊toolbar上那個button,會彈出如下對話框:


    程序運行也沒啥錯誤。


    問題分析:
    其實我覺得這個問題是很難繞過去的。對于同一個插件,因為內部的類需要互相引用和互相使用,所以必須使用同一個類加載器來加載。所以,這個插件只要expose出來一個包,那么外部的插件就可以通過包中的任何一個類來得到加載這個插件中的類的類加載器,然后就可以通過reflect愛做啥做啥了。

    換一個角度可能更好理解這個問題為什么難以繞過去。假設VisiableClass需要用到InvisiableClass,雖然InvisiableClass沒有暴露出來,但是在正常的使用VisiableClass的時候,需要先加載VisiableClass類,而加載VisiableClass的時候JVM就會隱式的加載InvisiableClass。這個過程和例子里現式的加載InvisiableClass沒啥本質不同。也就是說,從ClassLoader的角度,很難判斷一個類的加載是正常的代碼還是為了突破bundle的訪問限制——它們都是在執行run方法時發生的類加載行為。

    或者是我有什么地方沒設置好?求解答。例子下載在此

    posted @ 2010-05-17 12:09 深夜兩點 閱讀(4806) | 評論 (8)編輯 收藏

    宅能量終于爆發了,書終于出版了。China Pub有售http://www.china-pub.com/196571

    posted @ 2010-04-27 20:47 深夜兩點 閱讀(1668) | 評論 (1)編輯 收藏

    在設計一個多線程程序的時候,首先要考慮好線程模型是怎樣的。設計線程模型的時候可以有多個考慮,比如使用線程池,使用多個線程處理任務,或者使用類似AWT/Swing中事件處理機制那樣,使用單個線程處理同一類的任務。

    posted @ 2010-04-26 16:33 深夜兩點 閱讀(244) | 評論 (0)編輯 收藏

    rt

    posted @ 2010-04-11 11:21 深夜兩點 閱讀(238) | 評論 (0)編輯 收藏

    自己寫的一個小程序,做個視頻冒充一下技術宅……


    程序經多次優化,終于能夠達到一個可以接受的性能了……莫言Java無效率,其實重要的還是要精雕細琢。至 少就繪制Julia Set而言,我這個程序比我見過的幾個cpp版本的要快的多。
    項目主頁地址:http://code.google.com/p/juliasetcreator/
    程序下載地址:http://code.google.com/p/juliasetcreator/downloads/list

    posted @ 2010-03-20 17:25 深夜兩點 閱讀(2625) | 評論 (2)編輯 收藏

    轉自http://static.icybear.net/%5BCN%5DProgrammer%20competency%20matrix.htm

    [譯文]程序員能力矩陣 Programmer Competency Matrix

    注意:每個層次的知識都是漸增的,位于層次n,也蘊涵了你需了解所有低于層次n的 知識。
    計算機科學 Computer Science
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    數據結構 不知道數組和鏈表的差異 能夠解釋和使用數組, 鏈表,字典等,并且能夠用于實際的編程任務。 了解基本數據結構時間和空間的折中,比如數組vs 鏈表,能夠解釋如何實現哈希表和處理沖突,了解優先隊列及其實現。 高等的數據結構的知識,比如B-樹、二項堆、斐波那契堆、AVL 樹、紅黑樹、伸展樹、跳躍表以及前綴樹等。
    算法 不能夠找出一個數組各數的平均值(這令人難以置信,但是我的確在應聘者 中遇到過) 基本的排序,搜索和數據的遍歷和檢索算法。 樹,圖,簡單的貪婪算法和分而治之算法,能夠適度了解矩陣該 層的含義。 能夠辨識和編寫動態規劃方案,良好的圖算法知識,良好的數值估算的知識,能夠辨別NP問題等。 Working with someone who has a good topcoder ranking would be an unbelievable piece of luck!
    編程體系 不知道何為編譯器、鏈接器和解釋器。 對編譯 器、鏈接器、解釋器有基本的了解。知道什么是匯編代碼以及在硬件層如何工作。有一些虛擬內存和分頁知識。 了解內核模式vs用戶模式, 多線程,同步原語以及它們如何實現,能夠閱讀匯編代碼。了解網絡如何工作,了解網絡協議和socket級別編程。 了解整個程序堆棧、 硬件(CPU+內存+中斷+微碼)、二進制代碼、匯編、靜態和動態鏈接、編碼、解釋、JIT(just-in-time)編譯、內存碎片回收、堆、棧、存 儲器編址…
    軟件工程 Software Engineering
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    源碼版本控制 通過日期備份文件夾 VSS和初級的 CVS/SVN用戶 熟練地使用CVS和SVN特性。知道如何分支和歸并,使用程序庫補丁安裝特性等 有分布式VCS 系統的知識。嘗試過Bzr/Mercurial/Darcs/Git
    自動化編譯 只知道在IDE下編譯 知道如何編譯在命令行 下編譯系統 能夠安裝一個腳本構建基本的系統 能夠安裝一個腳本來構建系統并且歸檔,安裝程序,生成發布記錄和給源 碼控制中的代碼分配標簽。
    自動化測試 認為所有的測試都是測試員的工作。 能夠編寫 自動化的單元測試,能夠為正在編寫的代碼提出良好的測試用例。 按照TDD (Test Driven Development)方式編寫代碼。 了解并且能夠有效自動化安裝,載入/性能和UI測試
    程序設計 Programming
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    問題分解 只有直線式的代碼,通過復制粘貼來復用 能夠把 問題分散到多個函數中 能夠想出可復用的函數/對象來解決大題的問題 使用適宜的數據結構和算法,寫出通用的/面向 對象的代碼來封裝問題的易改變的層面。
    系統分解 N想不出比單一的文件/類更好的層面 如果不在 同一平臺或沒采用相同的技術,能夠把問題空間和設計方案分解。 能夠設計跨技術/平臺的系統。 能夠在多個產品線和 與外部體系一體化中虛擬化和設計復制的系統。同時也能夠設計支持系統監視、報告、故障恢復等。
    交流 不能向同伴表達想法/主意。匱乏拼寫和語法的能力。 同 伴能了解你在說什么。有良好的拼寫和語法能力。 能夠和同伴進行高效的交流 能夠使用清晰的方式了解和交流想法/設計 /主意/細則,能適應每種環境的交流 This is an often under rated but very critical criteria for judging a programmer. With the increase in outsourcing of programming tasks to places where English is not the native tongue this issue has become more prominent. I know of several projects that failed because the programmers could not understand what the intent of the communication was.
    同一文件中代碼組織 同一文件中組織沒有依據 按照邏輯 性或者易接近的方法 代碼分塊和對于其他源文件來說是易于是釋,引用其他源文件時有良好的注釋 文檔頭部有許可聲 明,總結,良好的注釋,一致的空格縮進。文檔外觀美觀。
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    跨文件代碼組織 沒夠想過給代碼跨文件組織 相關文件按文件 夾分組 每個物理文件都有獨立的目的,比如一個類的定義,一個特性的實現等。 代碼在物理層組織緊密,在文件名上與 設計和外觀相匹配,可以通過文件分布方式洞察設計理念。
    源碼樹組織 一切都放在一個文件夾內 初步地將代碼分散進 對應邏輯的文件夾。 沒有循環依賴,二進制文件,庫,文檔,構建,第三方的代碼都組織進合適的文件夾內。 源碼樹的 物理布局與邏輯層次、組織方式相匹配。可以通過目錄名稱和組織方式洞察設計理念。 The difference between this and the previous item is in the scale of organization, source tree organization relates to the entire set of artifacts that define the system.
    代碼可讀性 單音節的名稱 (在國內應該是那些類似用漢語拼音命名的習慣) 對文件、變量、類、方法等,有良好的命名。 沒有長函數、注釋解釋不常規的代碼,bug修復,代碼假設。 代 碼假設驗證使用斷言,自然的代碼流,沒有深層嵌套的條件和方法
    防御性編碼 不知道這個概念 檢查代碼中所有的參數,對關鍵 的假設進行斷言 確保檢查了返回值和使代碼失敗的異常。 有自己的庫來幫助防御性編程、編寫單元測試模擬故障
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    錯誤處理 只給樂觀的情形編碼 基本的代碼錯誤處理,拋出 異常/生成錯誤 確保錯誤/異常留在程序中有良好的狀態,資源,連接,內存都有被合適的清理。 在編碼之前察覺可能 出現的異常,在代碼的所有層次中維持一致性的異常處理策略,提出整個系統的錯誤處理準則。
    IDE IDE大部分用來進行文本編輯 了解其周圍的接 口,能夠高效地通過菜單來使用IDE 了解最常操作的鍵盤快捷鍵 編寫自定義宏
    API 需要頻繁地查閱文檔 把最頻繁使用的API記在腦 子里 廣闊且深入的API知識。 為了使實際任務中常用API使用更加便捷,編寫過API的上層庫,填補API之間 的缺口。 E.g. of API can be Java library, .net framework or the custom API for the application
    框架 沒有使用過主平臺外的任何框架 聽過但沒用過平臺下 流行的可用框架 在專業的職位中使用過一個以上的框架,通曉各框架的特色。 某框架的作者
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    需求分析 接受給定的需求和代碼規格 能對規格的遺漏提出 疑問 了解全面情況,提出需要被規格化的整體范圍。 能夠提出更好的可選方案,根據經驗的浮現給出需求
    腳本 不具備腳本工具的知識 批處理文件/shell腳本 Perl/Python/Ruby/VBScript/Powershell 寫過并且發表過可重用的代碼
    數據庫 認為Excel就是數據庫 知道基本的數據庫概 念,規范化、ACID(原子性Atomicity、一致性Consistency、隔離性Isolation、持久性Durability)、事務化,能 夠寫簡單的select語句 能夠牢記在運行時必要查詢中設計良好的規范化數據庫模式, 精通用戶視圖,存儲過程,觸發器和用戶定義類型。知道聚集與非聚集索引之間的差異。精通使用ORM(Object Relational Mapping對象關系映射)工具 能做基本的數據庫管理,性能優化,索引優化,編寫高級的select查詢,能夠使用相關sql來替 換游標,理解數據內部的存儲,了解如何鏡像、復制數據庫。知道兩段數據提交如何工作
    經驗 Experience
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    專業語言經驗 命令式語言和面向對象語言 命令式語言,面向對象語言和說明型語言(SQL),如果了解靜態類型vs動態類型,弱類型vs強類型則有加分 函數式語言,如果了解延 緩求值,局部套用函數,延續則有加分 并發語言(Erlang, Oz) 邏輯語言(Prolog)
    專業平臺經驗 1 2-3 4-5 6+
    專業經驗年齡 1 2-5 6-9 10+
    領域知識 沒有該領域的知識 在該領域中曾經至少為一個 產品工作過 在同一領域中為多個產品工作過 領域專家。在該領域設計和實現數種產品/方案。精通該領域使用的標準條款 和協議
    學識 Knowledge
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    工具知識 僅限于主要的IDE(VS.Net, Eclipse等) 知 道一些流行和標準工具的備選方案 對編輯器、調試器、IDE、開源的備選方案有很好的了解。比如某人了解大多數Scott Hanselman的威力工具列表中的工具,使用過ORM工具。 實際地編寫過工具和腳本,如果這些被發布則有加分
    語言接觸 命令式語言和面向對象語言 命令式語言、面向對象 語言和說明型語言(SQL),如果了解靜態類型vs動態類型、弱類型vs強類型則有加分 函數式語言,如果了解延緩求值、局部套用函 數、continuations (源于scheme中的一種高級控制結構)則有加分 并發語言(Erlang, Oz) 邏輯語言(Prolog)
    代碼庫知識 從來沒有查詢過代碼庫 基本的代碼層知識,了 解如果構建系統 良好的代碼庫工作知識,實現過幾次bug修復或者完成了一些細小的特性 實現了代碼庫中多個大型特 性,能夠輕松地將多數特性的需求變更具體化,從容地處理bug修復。
    下一代技術知識 從來沒聽說過即將到來的技術 聽說過某領 域即將到來的技術 下載過alpha preview/CTP/beta版本,并且讀過一些文章和手冊 試用過預覽 版而且實際地構建過某物,如果共享給其他人的話則有加分
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    平臺內部 對平臺內部毫無所知 有平臺基本的內部工作的 知識 深度的平臺內部知識,能夠設想平臺如何將程序轉換成可執行代碼。 編寫過增強平臺或者為其平臺內部提供信息的 工具。比如,反匯編工具,反編譯工具,調試工具等。
    書籍 菜鳥系列,21天系列,24小時系列,蠢貨系列... 《代 碼大全》,《別讓我思考》, 《精通正則表達式》 《設計模式》,《人件》,《代碼珠璣》,《算法設計手冊》,《程序員修煉之道》, 《人月神話》 《計算機程序設計與解釋》,《事務處理:概念與技術》,《計算機程序設計模型》,《計算機程序設計藝術》,《數據庫系統 導論》 C.J Date版,《Thinking Forth》 ,《Little Schemer》(沒找到其中譯本)
    博客 聽過但是從來抽不出空去接觸 閱讀一些科技/編程 /軟件工程的博客,并且經常的收聽一些播客 維護一些博客的鏈接,收集博主分享的有用的文章和工具 維護一個在編程方 面,分享有個人見解和思考的博客
    Creative Commons License
    程序員能力矩陣 by XGuru is licensed under a Creative Commons 署名-非商業性使用-相同方式共享 2.5 中國大陸 License. 原文請看 這 里
    Thanks to bearice for debugging.
    Thanks to John Haugeland for a reformatting of it that works much more nicely on the web.

    posted @ 2010-03-14 23:35 深夜兩點 閱讀(239) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 免费人成视频在线观看免费| 朝桐光亚洲专区在线中文字幕 | 香蕉视频在线观看亚洲| 免费的黄网站男人的天堂| 国产免费黄色大片| 美女黄频免费网站| 亚洲国产黄在线观看| h视频免费高清在线观看| 亚洲毛片αv无线播放一区| 成全视频在线观看免费| 亚洲bt加勒比一区二区| 亚洲一区二区三区免费视频| 激情五月亚洲色图| 成人永久免费高清| 国产A∨免费精品视频| 久久精品国产96精品亚洲| 最近中文字幕大全中文字幕免费| 亚洲视频一区在线播放| 免费一本色道久久一区| 激情小说亚洲图片| 亚洲高清专区日韩精品| 午夜国产精品免费观看| 老子影院午夜伦不卡亚洲| 中文字幕亚洲乱码熟女一区二区 | 国产AV旡码专区亚洲AV苍井空 | 国产aⅴ无码专区亚洲av麻豆| 水蜜桃视频在线观看免费播放高清| 久久精品国产精品亚洲艾草网| 国产91色综合久久免费分享| 亚洲国产成人手机在线观看| 亚洲伊人成无码综合网| 成人免费视频69| 黄色一级毛片免费看| 亚洲综合久久综合激情久久| 成人毛片18女人毛片免费视频未| 欧洲美女大片免费播放器视频| 亚洲最大福利视频网站| 日本一道一区二区免费看| 野花香在线视频免费观看大全 | 老司机福利在线免费观看| 久久夜色精品国产嚕嚕亚洲av|