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

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

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

    2010年3月20日

    例子下載在此

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

    為了演示這個(gè)問題,先在eclipse中創(chuàng)建一個(gè)插件UtilityLibrary

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


    VisiableClassVisiableClass類的內(nèi)容很簡單:
    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";
        }
    }


    其實(shí)主要就是打印出相應(yīng)的信息。類代碼幾乎是一樣的。

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


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


    當(dāng)然,使用VisiableClass是沒問題的。下面通過VisiableClass來將InvisiableClass拽出來,SampleAction類的源代碼如下,只要關(guān)心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");來加載本不應(yīng)該被外部所見的Invisiable類。因?yàn)樵贓clipse中,每個(gè)插件使用一個(gè)ClassLoader,所以用來加載VisiableClass類的ClassLoader也同樣負(fù)責(zé)加載在同一個(gè)插件中的InvisiableClass類。這樣InvisiableClass就在插件外部被加載成功了。類加載成功后,剩下的事情就是順?biāo)浦哿耍瑒?chuàng)建個(gè)實(shí)例然后使用反射調(diào)用相應(yīng)的方法。
    程序運(yùn)行的時(shí)候,點(diǎn)擊toolbar上那個(gè)button,會彈出如下對話框:


    程序運(yùn)行也沒啥錯(cuò)誤。


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

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

    或者是我有什么地方?jīng)]設(shè)置好?求解答。例子下載在此

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

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

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

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

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

    rt

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

    自己寫的一個(gè)小程序,做個(gè)視頻冒充一下技術(shù)宅……


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

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

    主站蜘蛛池模板: 99精品免费视品| 亚洲香蕉免费有线视频| 日本无吗免费一二区| 亚洲综合色丁香婷婷六月图片 | 亚洲欧洲国产日韩精品| 免费国产在线视频| 亚洲大片在线观看| 国产91免费在线观看| 中文字幕亚洲综合小综合在线| 成熟女人特级毛片www免费| 亚洲国产成人久久综合| 免费国产成人高清在线观看麻豆 | 6080午夜一级毛片免费看6080夜福利 | 亚洲色大成网站WWW久久九九| 亚洲视屏在线观看| 午夜国产精品免费观看| 亚洲乱码无人区卡1卡2卡3| 国产精品免费小视频| yellow视频免费看| 亚洲AV永久无码精品水牛影视| 日韩午夜理论免费TV影院| 色老板亚洲视频免在线观| 亚洲精品成人区在线观看| 国产一级黄片儿免费看| 亚洲自偷精品视频自拍| 永久黄网站色视频免费直播 | 91老湿机福利免费体验| 亚洲成人激情小说| 亚洲一区二区三区香蕉| 在线视频免费观看高清| 一级成人生活片免费看| 亚洲美女免费视频| 免费在线观看的黄色网址| 污视频在线观看免费| 亚洲乱人伦中文字幕无码| 亚洲AV一宅男色影视| 曰皮全部过程视频免费国产30分钟 | 亚洲成_人网站图片| 亚洲日本va在线视频观看| 最近中文字幕免费mv视频8| 最近免费mv在线观看动漫 |