Spring resource prefixes such as file: and http: are also supportedm , Resources loaded using such prefixes may come from any location, they are not restricted to being defined within the resource-loading bundle or its attached fragments. OSGi platforms may define their own unique prefixes for accessing bundle contents. For example, Equinox defines the bundleresource: and bundlentry: prefixes. These platform specific prefixes may also be used with Spring OSGi, at the cost, of course, of tying yourself to a particular OSGi implementation.原本的file: , http: 也是可以使用的, 並不被限制於自身的bundle位置, osgi 的平台每個實作的不一樣,所以預設的prefix 也許會不一樣,Equinox 就是bundleresource: and bundlentry: ,如果你對Spring 的Resource 不太了解的話,建議可以先看這份官方的Doc Link-> Spring 3.x - 4. Resources 。
一樣先建立二個Bundle , 2個Bundle 的結構如下
OSGIApp.Sample.OSGiSample
OSGIApp.Sample.OSGiSample2
然後在OSGIApp.Sample.OSGiSample 裡面的Activator 裡面取Resource , code如下
package com.my; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.io.Resource; import org.springframework.osgi.context.BundleContextAware; public class Activator implements ApplicationContextAware,BundleContextAware { ApplicationContext application; Bundle bundle; Bundle bundle2; BundleContext btx; public void start() throws BundleException, IOException{ //default setting,If no prefix is specified, the bundle space (osgibundle:) will be used. Resource res = application.getResource("/TxtFile/ResoureText.txt"); System.out.println("Resource(Default osgibundle) = " res); System.out.println("Resource(Default osgibundle) = " res.getURI()); System.out.println("Resource(Default osgibundle) = " res.getURL()); File f = res.getFile(); System.out.println("File(osgibundle) getAbsolutePath = " f.getAbsolutePath() ); System.out.println("File(osgibundle) getPath = " f.getPath() ); System.out.println(); //osgibundlejar prefix , Searches only the bundle jar. Provides low-level access. //using the same semantics as the Bundle.getEntry method. Delegates internally to the Bundle.findEntries . Resource res2 = application.getResource("osgibundlejar:/TxtFile/ResoureText.txt"); System.out.println("Resource2(osgibundlejar) = " res2); System.out.println("Resource2(osgibundlejar) = " res2.getURI()); System.out.println("Resource2(osgibundlejar) = " res2.getURL()); try{ File f2 = res2.getFile(); // can't use it. // File f2 = new File(res2.getURI().toString()); //it's work. System.out.println("File(osgibundlejar) getAbsolutePath = " f2.getAbsolutePath() ); System.out.println("File(osgibundlejar) getPath = " f2.getPath() ); }catch(FileNotFoundException ex){ System.out.println(ex); } System.out.println(); //classpath:(the same as classpath*:) prefix , Searches the bundle classloader (the bundle, all imported packages and required bundles). Resource res3 = application.getResource("classpath:/TxtFile/ResoureText.txt"); System.out.println("Resource3(classpath) = " res3); System.out.println("Resource3(classpath) = " res3.getURI()); System.out.println("Resource3(classpath) = " res3.getURL()); File f3 = res3.getFile(); System.out.println("File(classpath) getAbsolutePath = " f3.getAbsolutePath() ); System.out.println("File(classpath) getPath = " f3.getPath() ); System.out.println(); //To use osgi framework that get resource from the osgi bundle. bundle = btx.getBundle(); System.out.println("Bundle GetResoruce = " bundle.getResource("/TxtFile/ResoureText.txt")); System.out.println("bundle getEntry = " bundle.getEntry("/TxtFile/ResoureText.txt")); File f4 = new File(bundle.getResource("/TxtFile/ResoureText.txt").toString()); System.out.println("File(classpath) getAbsolutePath = " f4.getAbsolutePath() ); System.out.println("File(classpath) getPath = " f4.getPath() ); System.out.println(); System.out.println("bundl2 = " bundle2); System.out.println("get uri = " bundle2.getResource("/XmlFolder/Test.xml")); System.out.println("Bundle2 GetResoruce = " bundle2.getResource("/XmlFolder/Test.xml")); System.out.println("bundle2 getEntry = " bundle2.getEntry("/XmlFolder/Test.xml")); File f5 = new File(bundle2.getResource("/XmlFolder/Test.xml").toString()); System.out.println("File(classpath) getAbsolutePath = " f5.getAbsolutePath() ); System.out.println("File(classpath) getPath = " f5.getPath() ); System.out.println(); // System.out.println("bundle = " bundle); //update sampe2 bundle // bundle.update(); } public void stop() throws BundleException{ //stop sample2 , // bundle.stop(); } // // public void setBundle(Bundle bundle) { // System.out.println("bnudle set"); // this.bundle = bundle; // } // public void setBundleContext(BundleContext bundleContext) { System.out.println("set bundle context "); this.btx= bundleContext; } public void setBundle2(Bundle bundle2) { this.bundle2 = bundle2; } public void setApplicationContext(ApplicationContext arg0) throws BeansException { this.application = arg0; } }
然後這邊是完整的Log清單
set bundle context Resource(Default osgibundle) = OSGi resource[/TxtFile/ResoureText.txt|bnd.id=60|bnd.sym=OSGIApp.Sample.OSGiSample] Resource(Default osgibundle) = bundleentry://60.fwk1834141/TxtFile/ResoureText.txt Resource(Default osgibundle) = bundleentry://60.fwk1834141/TxtFile/ResoureText.txt File(osgibundle) getAbsolutePath = C:\Eclipse-Virgo-WebServer\work\org.eclipse.virgo.kernel.deployer_2.1.0.RELEASE\staging\global\bundle\OSGIApp.Sample.OSGiSample\1.0.0\OSGiSample.jar\TxtFile\ResoureText.txt File(osgibundle) getPath = C:\Eclipse-Virgo-WebServer\work\org.eclipse.virgo.kernel.deployer_2.1.0.RELEASE\staging\global\bundle\OSGIApp.Sample.OSGiSample\1.0.0\OSGiSample.jar\TxtFile\ResoureText.txt Resource2(osgibundlejar) = OSGi resource[osgibundlejar:/TxtFile/ResoureText.txt|bnd.id=60|bnd.sym=OSGIApp.Sample.OSGiSample] Resource2(osgibundlejar) = bundleentry://60.fwk1834141/TxtFile/ResoureText.txt Resource2(osgibundlejar) = bundleentry://60.fwk1834141/TxtFile/ResoureText.txt java.io.FileNotFoundException: OSGi resource[osgibundlejar:/TxtFile/ResoureText.txt|bnd.id=60|bnd.sym=OSGIApp.Sample.OSGiSample] cannot be resolved to absolute file path Resource3(classpath) = OSGi resource[classpath:/TxtFile/ResoureText.txt|bnd.id=60|bnd.sym=OSGIApp.Sample.OSGiSample] Resource3(classpath) = file:/C:/Eclipse-Virgo-WebServer/work/osgi/configuration/org.eclipse.osgi/bundles/36/data/store/org.eclipse.osgi/bundles/60/1/bundlefile/TxtFile/ResoureText.txt Resource3(classpath) = file:/C:/Eclipse-Virgo-WebServer/work/osgi/configuration/org.eclipse.osgi/bundles/36/data/store/org.eclipse.osgi/bundles/60/1/bundlefile/TxtFile/ResoureText.txt File(classpath) getAbsolutePath = C:\Eclipse-Virgo-WebServer\work\osgi\configuration\org.eclipse.osgi\bundles\36\data\store\org.eclipse.osgi\bundles\60\1\bundlefile\TxtFile\ResoureText.txt File(classpath) getPath = C:\Eclipse-Virgo-WebServer\work\osgi\configuration\org.eclipse.osgi\bundles\36\data\store\org.eclipse.osgi\bundles\60\1\bundlefile\TxtFile\ResoureText.txt Bundle GetResoruce = file:/C:/Eclipse-Virgo-WebServer/work/osgi/configuration/org.eclipse.osgi/bundles/36/data/store/org.eclipse.osgi/bundles/60/1/bundlefile/TxtFile/ResoureText.txt bundle getEntry = bundleentry://60.fwk1834141/TxtFile/ResoureText.txt File(classpath) getAbsolutePath = C:\Eclipse-Virgo-WebServer\file:\C:\Eclipse-Virgo-WebServer\work\osgi\configuration\org.eclipse.osgi\bundles\36\data\store\org.eclipse.osgi\bundles\60\1\bundlefile\TxtFile\ResoureText.txt File(classpath) getPath = file:\C:\Eclipse-Virgo-WebServer\work\osgi\configuration\org.eclipse.osgi\bundles\36\data\store\org.eclipse.osgi\bundles\60\1\bundlefile\TxtFile\ResoureText.txt bundl2 = OSGIApp.Sample.OSGiSample2_1.0.0 [57] get uri = file:/C:/Eclipse-Virgo-WebServer/work/osgi/configuration/org.eclipse.osgi/bundles/36/data/store/org.eclipse.osgi/bundles/57/2/bundlefile/XmlFolder/Test.xml Bundle2 GetResoruce = file:/C:/Eclipse-Virgo-WebServer/work/osgi/configuration/org.eclipse.osgi/bundles/36/data/store/org.eclipse.osgi/bundles/57/2/bundlefile/XmlFolder/Test.xml bundle2 getEntry = bundleentry://57.fwk1834141/XmlFolder/Test.xml File(classpath) getAbsolutePath = C:\Eclipse-Virgo-WebServer\file:\C:\Eclipse-Virgo-WebServer\work\osgi\configuration\org.eclipse.osgi\bundles\36\data\store\org.eclipse.osgi\bundles\57\2\bundlefile\XmlFolder\Test.xml File(classpath) getPath = file:\C:\Eclipse-Virgo-WebServer\work\osgi\configuration\org.eclipse.osgi\bundles\36\data\store\org.eclipse.osgi\bundles\57\2\bundlefile\XmlFolder\Test.xml
這邊要注意一下預設的prefix 是osgibundle: , 須要注意的是osgibundlejar: 這邊只提供low-lever access, 如果直接Resource.getFile() 會出現FileNotFoundException, 需使用getURI() 來取得檔案, 可以注意到預設的osgibundle 取出的檔案PATH跟其他的有不一樣,在Eclipse Virgo裡面是去jar檔的位置尋找, osgibundlejar則是跟osgi預設的行為很象, Equinox 裡面是設定bundleresource: and bundlentry: prefixes。
Reference:
Spring dm文件裡面有介紹, 相關的prefix
Table 6.1. OSGi resource search strategies
OSGi Search Strategy | Prefix | Explanation |
---|---|---|
Class Space | classpath: | Searches the bundle classloader (the bundle, all imported packages and required bundles). Forces the bundle to be resolved. This method has similar semantics to Bundle#getResource(String) |
Class Space | classpath*: | Searches the bundle classloader (the bundle and all imported packages and required bundles). Forces the bundle to be resolved. This method has similar semantics to Bundle#getResources(String) |
JAR File (or JarSpace) | osgibundlejar: | Searches only the bundle jar. Provides low-level access without requiring the bundle to be resolved. |
Bundle Space | osgibundle: | Searches the bundle jar and its attached fragments (if there are any). Does not create a class loader or force the bundle to be resolved. |
Chapter 6. Bundles and Application Contexts : 6.4. The Resource Abstraction
阅读 springdm in action 笔记--Spring DM extenders Link
沒有留言:
張貼留言