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

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

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

    子在川上曰

      逝者如斯夫不舍晝夜
    隨筆 - 71, 文章 - 0, 評論 - 915, 引用 - 0
    數據加載中……

    在Eclipse RCP中使用Spring

    注:在發完此文后,我驚奇的發現在新版Eclipse中(我用的是3.2M6)已經不需要轉換ClassLoader。估計這是RCP的一個BUG,已經被FIX。希望各位同學共同驗證一下,如果是這樣的話,這篇文章也就沒有什么意義了。


    在RCP中使用Spring,最關鍵的一點在于spring配置文件的讀取,因為RCP使用自己的ClassLoader,所以用通常的方法是無法裝載Spring的配置文件。解決的思路是:在讀取Spring配置文件時將RCP的ClassLoader暫時換一下。

    在這里我根據Spring配置文件在項目中的存放位置,給出兩種辦法。

    一、配置文件存放在源代碼根目錄下。

    假設我有一個叫admin_console的項目,我把Spring的配置文件myspring.xml放在源代碼根據目錄src下,如下圖所示
    admin_console
    ????? --src
    ?????????? --cn????? //包名
    ?????????????? --com
    ????????????????? --chengang?
    ????????????????????? ---......???? //源代碼類
    ????????? --myspring.xml????? //Spring配置文件,位于src目錄下和cn目錄平級
    ??????--bin
    ????? --lib
    ????? --icons
    ????? --properties


    那么我們在RCP程序中可以這樣來裝載myspring.xml
    ????????ClassLoader?oldLoader?=?Thread.currentThread().getContextClassLoader();
    ????????
    try?{
    ????????????Thread.currentThread().setContextClassLoader(this.getClass()
    .getClassLoader());
    ????????????
    ctx?=?new?ClassPathXmlApplicationContext("/myspring.xml");
    ????????}?finally?{
    ????????????Thread.currentThread().setContextClassLoader(oldLoader);
    ????????}



    二、配置文件存放在項目根目錄的某個子目錄下

    項目根目錄和源代碼根目錄是不同的兩個概念。如上圖的項目結構中,src是源代碼根目錄,admin_console是項目根目錄,那么properties就是項目根目錄下的一個子目錄。

    如果將myspring.xml放入到properties目錄中,以上的讀取代碼就沒用了,讀取方法如下:

    ????????ClassLoader?oldLoader?=?Thread.currentThread().getContextClassLoader();
    ????????
    try?{
    ????????????Thread.currentThread().setContextClassLoader(this.getClass()
    .getClassLoader());
       ctx?=?new FileSystemXmlApplicationContext(ProjectUtil.toFullPath("properties/myspring.xml"));
    ????????}?finally?{
    ????????????Thread.currentThread().setContextClassLoader(oldLoader);
    ????????}

    其中ProjectUtil.toFullPath是我自己寫的一個方法,主要是得到myspring.xml的絕對路徑,其代碼如下:

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    ?
    import org.eclipse.core.runtime.FileLocator;
    import org.eclipse.core.runtime.Path;
    import org.eclipse.ui.plugin.AbstractUIPlugin;
    ?
    import com.wxxr.management.admin.console.AdminConsolePlugin;
    ?
    /**
    ?* 用于插件項目和非插件項目,提供兩者通用的方法接口
    ?* @author chengang 2006-3-30
    ?*/
    public class ProjectUtil {
    ?
    ??? private static AbstractUIPlugin plugin = AdminConsolePlugin.getDefault();
    ?
    ??? private ProjectUtil() {}
    ?
    ??? /**
    ???? * 判斷當前的運行狀態是否為插件方式
    ???? * @return true=插件方式運行
    ???? */
    ??? private static boolean isPlugin() {
    ??????? return plugin != null;
    ??? }
    ?
    ??? public static URL getURL(String path) {
    ??????? if (isPlugin())//如果是插件
    ??????????? return FileLocator.find(plugin.getBundle(), new Path(path), null);
    ??????? else
    ??????????? try {
    ??????????????? return new URL("file:" + path);
    ??????????? } catch (MalformedURLException e) {
    ??????????????? throw new RuntimeException(path + " is error", e);
    ??????????? }
    ??? }
    ?
    ??? public static InputStream getInputStream(String path) {
    ??????? URL url = getURL(path);
    ??????? try {
    ??????????? return url.openStream();
    ??????? } catch (IOException e) {
    ??????????? throw new RuntimeException(e);
    ??????? }
    ??? }
    ?
    ??? public static String toFullPath(String path) {
    ??????? if (isPlugin()) {
    ??????????? try {
    ??????????????? return FileLocator.toFileURL(ProjectUtil.getURL(path)).getPath();
    ??????????? } catch (IOException e) {
    ??????????????? throw new RuntimeException(path + " toFullPath is fault", e);
    ??????????? }
    ??????? } else {
    ??????????? return path;
    ??????? }
    ??? }
    ?
    }


    三、總結

    上面兩種方式那一種更好呢?應該是第二種。一般來說,源代碼的編譯文件會打成一個jar包(其實不打成一個JAR包也可以的,我在很多以前就嘗試過將class文件松散的部署,如果哪個類要修改,修改后就只部署覆蓋這個class,看起來也挺方便。不過這種方式不是最佳實踐,不推薦正式發布時使用,一不心可能引起依賴它的其他類出現問題。)。如果用第一種方式在項目打包后,myspring.xml會打包到jar文件中,這樣不利于今后對myspring進行動態修改。如果用第二種就沒有這種缺點。

    很多時候,在Eclipse開發環境中,運行RCP程序沒有問題。但導出項目后,在獨立的環境中卻報配置文件(不光是Spring)找不到的錯誤,解決的方法都基本與此相同。

    posted on 2006-04-26 17:44 陳剛 閱讀(7512) 評論(22)  編輯  收藏 所屬分類: Eclipse

    評論

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
    try {
    Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
    ctx = new ClassPathXmlApplicationContext("/myspring.xml");
    } finally {
    Thread.currentThread().setContextClassLoader(oldLoader);
    }
    1,這端代碼放到RCP的Application中可以嗎?
    2,ClassPathXmlApplicationContext在RCP開發中沒有這個類,如果按同樣的方法來配置Hibernate應該使用那個類呢?
    3,恕我愚笨能給詳細教教小弟配置一下嗎?
    2006-08-23 21:42 | qiuliang

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    其實我得,目的就是在RCP中配置Hibernate!spring我并不懂,陳先生,如果我問的不對還請你見涼,但是我真的很渴望知道怎么在RCP中配置和使用Hibernate!
    2006-08-23 21:45 | qiuliang

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @qiuliang
    關于hibernate看這篇文章
    http://m.tkk7.com/chengang/archive/2006/08/24/65484.html
    2006-08-24 12:29 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    這個問題貌似并沒有在ECLIPSE3.2中被完美解決。事實上也不是一個需要被解決的BUG。我曾經碰到過相同的問題,特地下載了ECLIPSE3.2試驗,但是并沒有成功。
    談談這個問題的根源:ECLIPSE的每個PLUGIN被自己專屬的CLASSLOADER所加載,專屬的CLASSLOADER也只能識別出當前PLUGIN下的類和配置文件,所以如果在當前PLUGIN下調用有依賴關系的另一個PLUGIN中的CLASS來動態加載當前PLUGIN下的類或者配置文件,那么錯誤就發生了,因為另一個PLUGIN的CLASSLOADER找不到它需要的類或者配置文件。
    ECLIPSE 3.1起對這個問題有一個優雅的解決方式,就是在上述的兩個PLUGIN的MANIFEST文件中配置注冊關系。

    陳師傅可以驗證一下我的說法。有空我可以貼出例證代碼。
    2006-09-26 11:42 | JIAWEI

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @JIAWEI
    是的新版Eclipse已經解決這個問題。
    2006-10-08 09:57 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    沒仔細研究過RCP的ClassLoader,不太理解陳師傅所說。

    我在插件開發中是使用spring的方法類似陳師傅說的第二種:放在properties文件夾下。不過我沒有用ProjectUtils這樣的方法找絕對路徑,我的方法是:
    1、將properties文件夾加入到項目的Runtime ClassPath中
    2、在getApplicatonContext時用ClassPathXmlApplicationContext就能去properties文件夾中去找;

    BTW:
    RCP的ClassLoader是不是就是在啟動時自動裝載所需類?
    2007-03-24 10:45 | 烏黑的大白馬

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    陳老師,請問下我用您的第二種方式的的話,那打包成Jar文件中會不會有什么錯誤,打包后應該只有一個bin目錄,沒有那個src和config(配置文件放這里),可以得到文件路徑嗎?
    2007-08-08 11:33 | liuraoxing

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    打包后不會有 bin目錄的,所以你打包的目錄結構錯了。
    具體請參考<Eclipse從入門到精通>第二版的,第32章'RCP項目的打包和發行',重點看圖32.13的下圖
    2007-08-10 08:37 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @烏黑的大白馬
    請看文章前面的紅色文字,這篇文章實際已經沒有意義。
    2007-08-10 08:39 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    為什么,我是安裝陳老師說的那樣,但是為什么還報這樣的錯誤,能給予說明下嗎?
    !ENTRY org.eclipse.osgi 4 0 2007-09-21 09:14:12.015
    !MESSAGE Application error
    !STACK 1
    org.eclipse.core.runtime.CoreException: Plug-in TestPlug was unable to load class testplug.Application.
    at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.throwException(RegistryStrategyOSGI.java:165)
    at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:149)
    at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:759)
    at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:51)
    at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:74)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
    at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
    at org.eclipse.core.launcher.Main.run(Main.java:977)
    at org.eclipse.core.launcher.Main.main(Main.java:952)
    org.eclipse.core.runtime.CoreException[1]: java.lang.ClassNotFoundException: testplug.Application
    at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:402)
    at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:347)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at org.eclipse.osgi.framework.internal.core.BundleLoader.loadClass(BundleLoader.java:278)
    at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:227)
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1245)
    at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:147)
    at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:759)
    at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:51)
    at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:74)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
    at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
    at org.eclipse.core.launcher.Main.run(Main.java:977)
    at org.eclipse.core.launcher.Main.main(Main.java:952)
    2007-09-21 09:15 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @cj_829cai
    unable to load class testplug.Application
    這一句報錯是關鍵。說明你的項目配置有問題,導致找不到Application類。
    2007-09-24 08:46 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    陳老師,有沒有簡單一點的例題?
    如果有時間話能發一下嗎?
    為了這個問題.我還專門買了你的書第二版里可惜沒有講到.
    caijin_001@163.com
    2007-09-24 10:03 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    這次是找不到spring文件.一開始我以為是導包的問題,我確定包是沒有問題的.我用一個測試類已經能正常使用spring.但是把這個正確的代碼拷貝過來就出問題了
    .我是按照你說的把類加載器轉換了一下.還是出現這樣的錯誤.急啊
    !ENTRY org.eclipse.ui.workbench 4 0 2007-09-24 09:55:44.635
    !MESSAGE Unable to create view ID MyCRP.view2: org/springframework/beans/factory/BeanFactory
    !STACK 0
    java.lang.NoClassDefFoundError: org/springframework/beans/factory/BeanFactory
    at com.view.TestView.seleteD(TestView.java:71)
    at com.view.TestView.createPartControl(TestView.java:55)
    at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:332)
    at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:197)
    at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:566)
    at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:290)
    at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:525)
    at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:140)
    at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:268)
    at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
    at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:394)
    at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1144)
    at org.eclipse.ui.internal.PartStack.setSelection(PartStack.java:1097)
    at org.eclipse.ui.internal.PartStack.showPart(PartStack.java:1311)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:601)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:532)
    at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:562)
    at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:244)
    at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:815)
    at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2436)
    at org.eclipse.ui.internal.WorkbenchWindow$6.run(WorkbenchWindow.java:2616)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
    at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:2597)
    at org.eclipse.ui.internal.WorkbenchWindow.busyOpenPage(WorkbenchWindow.java:658)
    at org.eclipse.ui.internal.Workbench.busyOpenWorkbenchWindow(Workbench.java:795)
    at org.eclipse.ui.internal.Workbench.doOpenFirstTimeWindow(Workbench.java:1437)
    at org.eclipse.ui.internal.Workbench.openFirstTimeWindow(Workbench.java:1388)
    at org.eclipse.ui.internal.WorkbenchConfigurer.openFirstTimeWindow(WorkbenchConfigurer.java:190)
    at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:708)
    at org.eclipse.ui.internal.Workbench.init(Workbench.java:1085)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1847)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at mycrp.Application.run(Application.java:18)
    at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
    at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
    at org.eclipse.core.launcher.Main.run(Main.java:977)
    at org.eclipse.core.launcher.Main.main(Main.java:952)
    2007-09-24 10:20 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    謝謝陳老師.我在你的Hibernate中找到的答案,謝謝了
    2007-09-25 11:29 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @cj_829cai
    舉一推三,聰明
    2007-09-26 01:12 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    陳老是,還有一個問題。不知道RCP里面能不能使用SWT的shell窗體?
    2007-09-29 18:07 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @cj_829cai
    你試過了嗎
    2007-09-29 20:54 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    我試過了。是可以用的。但是有一個問題。就是shell窗口是沒有辦法,彈出需要在任務欄里點擊才能現實出窗體。不知道這是什么原因?
    2007-10-09 15:09 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    @cj_829cai
    那是shell的參數沒有設置好。參考一樣本書SWT內容中關于shell的介紹。
    2007-10-10 08:49 | 陳剛

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    陳老師。能否把TitleAreaDialog變成非模式的窗口?
    2007-10-16 18:29 | cj_829cai

    # re: 在Eclipse RCP中使用Spring  回復  更多評論   

    com.wxxr.management.admin.console.AdminConsolePlugin;
    請教這一個包名是什么? 我沒找到相應的jar文件。
    2008-06-18 19:04 | win

    # re: 在Eclipse RCP中使用Spring解析問題  回復  更多評論   

    你好,我用你的方法,文件找到了。可是解析出現了不少問題,求指導
    2014-05-20 09:15 | 王傳
    主站蜘蛛池模板: 亚洲成人免费电影| eeuss免费天堂影院| 无码午夜成人1000部免费视频| 亚洲无码精品浪潮| 国产精品免费观看视频| 亚洲午夜久久久久久久久久| 国产区在线免费观看| 亚洲熟妇无码AV在线播放| 国产中文字幕在线免费观看| 亚洲va无码专区国产乱码| A片在线免费观看| 色婷婷亚洲十月十月色天| 免费无码中文字幕A级毛片| 美美女高清毛片视频黄的一免费| 亚洲精品欧洲精品| 亚洲精品tv久久久久久久久久| 国产午夜亚洲精品国产成人小说| 亚洲短视频在线观看| 另类免费视频一区二区在线观看| 亚洲av中文无码乱人伦在线r▽ | 999在线视频精品免费播放观看| 亚洲欧洲国产成人精品| 在线免费观看色片| 又长又大又粗又硬3p免费视频| 亚洲色无码专区在线观看| 久久精品人成免费| 亚洲色偷偷偷综合网| 在线日韩日本国产亚洲| 久久w5ww成w人免费| 国产精品久久久久久亚洲影视| 亚洲中文字幕无码爆乳av中文| 亚洲一区二区在线免费观看| 在线综合亚洲欧洲综合网站 | 国产成人精品免费久久久久| 亚洲自偷自拍另类图片二区| 日日AV拍夜夜添久久免费| 在线观看免费黄网站| 亚洲色偷偷综合亚洲av78| 亚洲色中文字幕无码AV| 青草草色A免费观看在线| 人成电影网在线观看免费|