DeepnightTwo
posts - 15, comments - 11, trackbacks - 0, articles - 0
BlogJava
首頁
新隨筆
聯(lián)系
管理
聚合
2010年5月17日
OSGi(Equinox)類加載的問題——使用ClassLoader突破bundle的訪問限制
例子下載在此
最近搞了個(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
:
其中u
tilitylibrary.expose包中的類會暴露給外部,而utilitylibrary.hide包中的類不會暴露給外部。在MANIFEST.MF中增加這個(gè)設(shè)置:
VisiableClass
和
VisiableClass
類的內(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)
|
編輯
收藏
<
2010年5月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
給我留言
查看公開留言
查看私人留言
隨筆檔案
(12)
2010年5月 (1)
2010年4月 (3)
2010年3月 (2)
2009年12月 (5)
2009年11月 (1)
文章檔案
(2)
2009年10月 (2)
搜索
最新評論
1.?re: 玩一下技術(shù)宅,數(shù)學(xué)之美——Julia Set分形
密集恐懼癥 看了 給跪
--yurenchen
2.?re: 玩一下技術(shù)宅,數(shù)學(xué)之美——Julia Set分形
是不是 有點(diǎn)卡..
--yurenchen
3.?re: OSGi(Equinox)類加載的問題——使用ClassLoader突破bundle的訪問限制
@深夜兩點(diǎn)
你看一下org.osgi.framework.Bundle的api javadoc。里邊有你需要的方法。
--臨遠(yuǎn)
4.?re: OSGi(Equinox)類加載的問題——使用ClassLoader突破bundle的訪問限制
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--表現(xiàn)表達(dá)
5.?re: OSGi(Equinox)類加載的問題——使用ClassLoader突破bundle的訪問限制
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--深夜兩點(diǎn)
閱讀排行榜
1.?OSGi(Equinox)類加載的問題——使用ClassLoader突破bundle的訪問限制(4806)
2.?玩一下技術(shù)宅,數(shù)學(xué)之美——Julia Set分形(2625)
3.?我的書出版了(1668)
4.?Java中的認(rèn)證(1116)
5.?計(jì)算機(jī)中的加密和認(rèn)證。(788)
評論排行榜
1.?OSGi(Equinox)類加載的問題——使用ClassLoader突破bundle的訪問限制(8)
2.?玩一下技術(shù)宅,數(shù)學(xué)之美——Julia Set分形(2)
3.?我的書出版了(1)
4.?線程模型設(shè)計(jì)(0)
5.?Java之父離開Oracle(0)
Copyright 深夜兩點(diǎn).
主站蜘蛛池模板:
国产99视频免费精品是看6
|
亚洲一卡二卡三卡四卡无卡麻豆
|
国产亚洲精品成人AA片新蒲金
|
亚洲av无码兔费综合
|
妞干网手机免费视频
|
亚洲国产精品无码av
|
亚洲精品av无码喷奶水糖心
|
啦啦啦高清视频在线观看免费
|
30岁的女人韩剧免费观看
|
亚洲av无码一区二区三区网站
|
国产精品免费一区二区三区四区
|
亚洲国产一区国产亚洲
|
蜜桃视频在线观看免费视频网站WWW
|
麻豆精品不卡国产免费看
|
精品少妇人妻AV免费久久洗澡
|
亚洲人成欧美中文字幕
|
一本色道久久88综合亚洲精品高清
|
老司机午夜精品视频在线观看免费
|
亚洲精品无码久久久
|
亚洲av乱码一区二区三区
|
女人张开腿等男人桶免费视频
|
性色av极品无码专区亚洲
|
亚洲中文字幕在线观看
|
国产好大好硬好爽免费不卡
|
精品久久亚洲中文无码
|
免费永久国产在线视频
|
两个人看的www高清免费观看
|
久久亚洲精品国产精品
|
伊人免费在线观看高清版
|
亚洲综合自拍成人
|
免费涩涩在线视频网
|
国产无限免费观看黄网站
|
麻豆精品国产免费观看
|
国产vA免费精品高清在线观看
|
热99re久久精品精品免费
|
一级做a毛片免费视频
|
亚洲依依成人精品
|
亚洲成av人片天堂网老年人
|
四虎最新永久免费视频
|
亚洲视频一区在线
|
久久www免费人成看片
|