??xml version="1.0" encoding="utf-8" standalone="yes"?> 最新进度: tomcat-users.xml拯到D:\Tomcat6\conf 目录下,覆盖原配|文?br />
认证框中的用户名和密码都?tomcatQ之后会q入下面q个面 Mark Little (ML): Hi Eric. Can you give us a bit of background about yourself and your relationship to OSGi? Eric Newcomer (EN): We had looked into OSGi a couple of years ago as a potential solution for delivering applications to mobile devices, but didn't really do anything with it. It seemed like an enterprise edition of OSGi had the potential to be really important to the industry, given the requirements presented at the Workshop, and I felt IONA could make a strong contribution to it. ML: OSGi has been around for quite a while, but it's only recently that it seems to have received a lot of attention. Why do you think that is the case? EN: What really got OSGi into the spotlight was Eclipse. And I think that's still probably how most people would know about OSGi – the Eclipse platform is an implementation of OSGi, and every Eclipse plug in that you download and install uses OSGi behind the scenes. But I would say it's been more than that – OSGi has a simple service programming model that fits with the current trend toward service orientation, and supports dynamic deployment, something that is growing increasingly attractive in enterprise IT environments. ML: What's IONAs interest in OSGi? EN: We are looking at OSGi the same way many other vendors are looking at it, as an enabling technology for dividing up a large software project and deploying the results. But we are also interested in the potential of the OSGi programming model for meeting basic enterprise IT requirements. We think of it as a deployment platform, programming model, and runtime with significant potential for improving SOA based applications, and the potential to create an important vendor eco-system around runtimes the way the Eclipse platform has created an eco-system around tools. It seems clear that the industry is ready for a lightweight alternative to JEE, and we are already seeing significant interest in the marriage of Spring and OSGi in this area for example. The infrastructure requirements for SOA are different than the requirements that drove the creation of infrastructure products such as JEE application servers and EAI brokers – SOA needs something more lightweight, something that represents more of an improvement or refinement than something entirely new. OSGi seemed to have a lot of potential in this area. ML: ESBs have been evolving for a number of years and yet all of a sudden most of the popular implementations have started to look at OSGi in one way or another. Do you think OSGi and ESB are a good match? EN: Absolutely. First of all there's the development and deployment aspect of OSGi, in which ESBs can be developed, deployed, and enhanced using OSGi services and bundles. This should help speed time to market for new ESB features and functions, and improve manageability of ESB deployments. Second there's the OSGi programming model, which has the potential to create a standard interface for accessing ESB functionality from a Java container. Ultimately I believe we are looking at the possibility of OSGi enabling a ‘best of breed' style approach to the ESB market, in which OSGi becomes the "platform" for the ESB and vendors develop OSGi bundles to plug in. In fact I'd go farther and say OSGi is a good match for SOA infrastructure in general, and we are seeing this come up in places such as JBI V2 and the proposal for the Eclipse SOA runtime project. ML: How is the work within the OSGi committee progressing? EN: At the June 28 meeting in Munich we passed from the initial requirements phase into the design phase, which I keep saying means the fun will really begin. As anyone who's worked in multiple organizations knows, each one has its own unique approach and process. The OSGi process starts with a formalization of requirements into RFPs (Request for Proposal) and then once some number of RFPs are approved by the Requirements Committee, the Expert Group members can start creating RFCs (Request for Comment), which are the design documents identifying proposed solutions to the requirements. After that (or perhaps concurrently) EG members can develop a reference implementation and then someone (preferably not the same people as those coding the RI) develop the conformance test. A specification is only complete once there's an RI and a conformance test. So we are still relatively at the beginning of the process, but making good progress. At the Enterprise Workshop last September ( announcement: http://www.osgi.org/news_events/osgi_workshop_091106.asp, results: http://www2.osgi.org/EnterpriseWorkshop/HomePage) initial requirements were gathered and prioritized (http://www2.osgi.org/EnterpriseWorkshop/Requirements). The EEG was created in December by the OSGi Board, and held its initial meeting at the end of January in Dublin, Ireland. At that time several "workstreams" were identified. Leaders were assigned to the various workstreams and from that the 13 or so current RFPs were created. A couple of weeks ago the EEG voted to submit seven of the RFPs for approval, so with that we are effectively starting on the design stage. Based on the RFPs submitted we will be spending a lot of time figuring out how to map existing enterprise technologies onto OSGi, such as Spring, SCA, JEE, JBI, Web services, and perhaps others. ML: What fundamental changes can we expect to see around OSGi in the next year or so? EN: I don't think we'll see any fundamental changes. I think what we are looking at is a range of potential extensions to existing capabilities in order to meet enterprise requirements. Anyone familiar with OSGi knows that it has its origins in the embedded space, first for home automation and then for automotive automation and mobile phone application management. So the question naturally comes up, when evaluating requirements for an enterprise edition of OSGi, whether it can be the same OSGi as the embedded edition or whether something else is needed. This always brings up the comparison with J2ME, J2SE, and J2EE (I guess these are all just JME, JSE, and JEE now since we are well past Java 2). But so far the answer is that we are definitely not going to be doing this with OSGi. The native OSGi mechanisms will be used to extend and enhance OSGi to meet the new requirements for use in enterprise IT environments, but the core OSGi will not change. The extensions that we'll be looking at are based on the RFPs that have been submitted, such as a better mapping of JEE components such as JNDI, JDBC, and RMI, including object serialization, improved Web application support, improved security to support deploying user code and vendor supplied code in the same JVM, how to access external systems from within OSGi (and vice versa), and how to discover services that might be deployed in a remote OSGi environment. ML: Some people have said that Sun should adopt OSGi as the container of choice for EE7. What do you think? MLQ有为Sun应该选择OSGI做ؓJEE7(java 7.0)的容器,你对此有何看法? Sun voted against JSR 291, which passed anyway, making OSGi officially part of JSE. But that gives some indication of Sun's view. Sun has also proposed JSR 277, for Java modularity, which appears to significantly overlap with OSGi. Sun has a great opportunity to embrace OSGi and base Java 7 on it, but even though there is no official statement it seems that they are leaning in the direction of overlapping rather than embracing OSGi. I hope Sun comes to their senses about OSGi sooner rather than later. On the other hand, perhaps it would be better if Sun continues to oppose OSGi, since things have gone well for OSGi so far.
在System Bundle(Equinox)中export: javax.servletQorg.extwind.osgi.service
实现HttpService注册Servlet和Resource
实现HttpService注册jsp 实现相同HttpContext注册地Servlet和Resource׃nServletContext
OSGiContext自动安装OSGi-App根目录中的jar?br />
Tomcat-OSGi QuickStart:
1. 准备工作
使用Extwind的Tomcat-OSGi是非常简单的Q首先下载不?M的rar文gQ其中包括以下内容:
extwind-tomcat-osgi-0.1-alpha.jar - Tomcat于Equinox集成jar包,它是必须的?br />
org.eclipse.osgi-0.1-Alpha.jar - 扩充q的Equinox osgi-frameworkQ它不是必须的,如果不用它Q将需要额外的bundleL持javax.servletQjavax.servlet.httpQorg.extwind.osgi.service.httpQ徏议用它Q因为在以后的版本中Q它有可能会成ؓ必须得?br />
osgiManager - Web ApplicationQ支持OSGi Application理的控制台Q通过它可以对每一个OSGi-App中的bundleq行理
osgiapp - 一个非常简单的Web ApplicationQ里面包含一个简单的bundleQ分别注册了一个static resourceQ一个jsp文gQ一个Servlet
server.xml - Tomcat 6.x的示例配|文Ӟ可选的
tomcat-users.xml - Tomcat 6.x 控制台用h限配|文Ӟ可选的
[ 点击q里下蝲 Tomcat-OSGi-QuickStart ]
2. 配置Tomcat 6.x
Tomcat 6.x 解压到某目录Q例?nbsp; D:\Tomcat6
extwind-tomcat-osgi-0.1-alpha.jar ?nbsp; org.eclipse.osgi-0.1-Alpha.jar 拯?nbsp;D:\Tomcat6\lib 目录?br />
osgiapp和osgiManager拯?D:\Tomcat6\webapps 目录?br />
打开server.xmlQ在<Host>节点中加?个属?className和hostConfigClassQ就像下面一PQ或者直接用本例提供的server.xmlQ?br />
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false" className="org.extwind.tomcat.catalina.core.ExtenseStandardHost" hostConfigClass="org.extwind.tomcat.catalina.startup.ExtenseHostConfig">
3. 开始?/strong>
l过以上单的准备和配|工作,现在已经可以开始用了Q启动tomcatQ访?br />
http://localhost:8080/osgiManager/html/list
点击OSGi ConsoleQ进?osgiapp的管理界?br />
可以看到Qorg.extwind.test.bundle已经被安装了Q因为OSGi-App启动时会根目录中的jar包作为bundle自动安装
控制台提供了4个功能:安装Q启动,停止Q卸载?在以后的版本中会逐步加强控制台的理功能?br />
在测试bundle中注册了3个资?br />
public class TestBundleActivator implements BundleActivator {
HttpService httpService = null;
public void start(BundleContext context) throws Exception {
ServiceReference sr = context.getServiceReference(HttpService.class
.getName());
httpService = (HttpService) context.getService(sr);
System.out.println("====================================================");
System.out.println(httpService.getClass().getName());
System.out.println("====================================================");
Dictionary<String, String> initparams = new Hashtable<String, String>();
initparams.put("servlet-name", "petstore");
initparams.put("load-on-startup", "2");
httpService.registerServlet("/test.do", new TestServlet(), initparams, null);
httpService.registerResources("/files", "/resource", null);
httpService.registerResources("*.jsp", "/resource", null);
}
public void stop(BundleContext context) throws Exception {
httpService.unregister("/test.do");
httpService.unregister("/files");
httpService.unregister("*.jsp");
}
}
3个资源的链接分别?br />
http://localhost:8080/osgiapp/files/test.ini
http://localhost:8080/osgiapp/test.do
http://localhost:8080/osgiapp/resource/date.jsp
q里的jspq没有用Equinox的JspServletQ而是作ؓ一个resourceq行注册
现在Q可以通过OSGi Console Ҏ块进行热插拔了?br />
到这里,已经基本使用了Tomcat-OSGi的简单功能,更多的功能正在开发中?br />
获取最新Tomcat-OSGi的源?
http://code.google.com/p/extwind
加入Extwind Group马上开始讨?br />
http://groups.google.com/group/extwind
The Package Admin service provides an interface to let the Management Agent make this decision.
Bundles能输出包到其他bundlesQ这个输出将会在输出bundle与引入bundle间发生一个依赖关p,当输出bundle被卸载或更新Ӟ对相关的׃n包必dZ个决定(相应动作Q。包理服务提供了一个接口让Management Agent来做q个军_?
7.1.1 Essentials
• Information – The Package Admin service must provide the sharing status of all packages. This should include information about the importing bundles and exporting bundle.
• Policy – The Package Admin service must allow a management agent to provide a policy for package sharing when bundles are updated and uninstalled.
• Minimal update – Only bundles that depend on the package that needs to be resolved should have to be restarted when packages are forced to be refreshed.
• Information – 包管理服务必L供所有包的共享状态,q应该包括输出bundle和引入bundle的相关信息?br />
• Minimal update – 依赖于需要被解析的包的bundles应该在这些包被强制刷新的时候被重启
7.1.2 Entities
• PackageAdmin – The interface that provides access to the internal Framework package sharing mechanism.
• ExportedPackage – The interface provides package information and its sharing status.
• RequiredBundle – The interfaces provides information about the bindings of required bundles.
• Management Agent – A bundle that is provided by the Operator to implement an Operator specific policy.
• PackageAdmin – 接口Q提供了Ҏ架内部包׃n机制的访问?br />
• ExportedPackage – 接口Q提供包的信息和包的׃n状态?br />
• RequiredBundle – 接口Q提供required bundles的绑定相关的信息
• Management Agent – 一个bundleQ由操作人员提供Q用于实现操作h员指定的{略?br />
7.1.3 Operation
The Framework’s system bundle should provide a Package Admin service for the Management Agent. The Package Admin service must be registered under the org.osgi.service.packageadmin.PackageAdmin interface by the system bundle. It provides access to the internal structures of the Framework related to package sharing, fragments and required bundles. This is an optional singleton service, so at most one Package Admin service must be
registered at any moment in time.
框架的系lbundle应该为Management Agent提供一个包理服务Q包理服务必须qlbundle注册在org.osgi.service.packageadmin.PackageAdmin的接口名下,它提供对框架内部l构中关于包׃nQ片D和required bundles的访问。这是一个可选的单例服务Q因此最多只有一个包理服务被注册?br />
The Framework must always leave the package sharing intact for packages exported by a bundle that is uninstalled or updated. A Management Agent can then choose to force the framework to refresh these packages using the Package Admin service. A policy of always using the most current packages exported by installed bundles can be implemented with a Management Agent that watches Framework events for bundles being uninstalled or updated, and then refreshes the packages of those bundles using the Package Admin service.
一个卸载或更新的bundle输出的包Q框架必LL保证q些包没有被使用Q这时Management Agent可以用包理服务选择强制框架hq些包。L使用安装bundle输出的通用包的{略可以被一个监听卸载或更新bundle的框架事件的Management Agent实现Q然后用包理服务h那些bundles的包?br />
7.2 Package Admin
The Package Admin service is intended to allow a Management Agent to define the policy for managing package sharing. It provides methods for examining the status of the shared packages. It also allows the Management Agent to refresh the packages and stop and restart bundles as necessary.
包管理服务允怸个Management Agent定义理包共享的{略Q它提供了检查共享包的状态的ҎQ也允许Management Agenth包,q在需要的时候停止和重启bundles
7.2.1 Package Sharing
The PackageAdmin class provides the following methods:
• getExportedPackage(String) – Returns an ExportedPackage object that provides information about the requested package. This information can be used to make the decision to refresh the package.
• getExportedPackages(Bundle) – Returns a list of ExportedPackage objects for each package that the given bundle exports.
• refreshPackages(Bundle[]) – The management agent may call this method to refresh the exported packages of the specified bundles. The actual work must happen asynchronously. The Framework must send a Framework.PACKAGES_REFRESHED when all packages have been refreshed.
• resolveBundles(Bundle[]) – The Framework must attempt to resolve the given bundles.
cPackageAdmin提供了一下方法:
• getExportedPackage(String) – q回一个提供了与requested package相关的信息的ExportedPackage对象Q这个信息可以决定是否需要刷新包?br />
• getExportedPackages(Bundle) – q回一个ExportedPackage对象的列表,l定的bundle所输出的包
• refreshPackages(Bundle[]) – management agent可以调用q个Ҏd新指定的bundle输出的包Q这个动作必L同步的。当所有包都被h后,框架必须发出一个Framework.PACKAGES_REFRESHED事g?br />
• resolveBundles(Bundle[]) – 框架必须试解析l定的bundles
7.2.2 Bundle Information
There is only the Bundle interface in the Framework API while bundles can perform different roles in the Framework. The Package Admin service provides access to this structural information.
• getBundle(Class) – Answer the bundle with the class loader that loaded the given class.
• getBundles(String,String)– Find a the set of bundles with the given bundle symbolic name and that fall within the given version. If the version is null, all bundles with the given bundle symbolic name are returned.
• getBundleType(Bundle) – Answer the type of the bundle. This is a bitmap of the different types. The following type is defined:
• BUNDLE_TYPE_FRAGMENT– The bundle is a fragment.
bundles可以在框架中扮演不同的角Ԍ但是q些bundle都在来自一个接口BundleQ包理服务提供了对q个l构信息的访问:
• getBundle(Class) – 查找一个bundleQ这个bundle的classloader加蝲了这个给定的c?br />
• getBundles(String,String)– 查找一个bundle集合Q通过l定的标记名和版本号Q如果版本号是nullQ那么将q回l定的标记名的bundles
• getBundleType(Bundle) – 查询bundle的类型。定义了以下cd
• BUNDLE_TYPE_FRAGMENT–bundle是个片段
7.2.3 Fragments and Required Bundles
The Package Admin service provides access to the network that is created by by requiring bundles and hosting fragments.
• getFragments(Bundle) – Return an array of bundles that currently act as fragment to the given bundle. If there are no fragments attached, null must be returned.
• getHosts(Bundle) – Return the bundle that acts as host to this fragment bundle. The given bundle should be an attached fragment bundle, otherwise null is returned.
• getRequiredBundles(String) – Return an array of RequiredBundle objects that match the given name (or all of the given name is null). The RequiredBundle object provides structural information about a required bundle.
包管理服务提供了对由需求bundle和主片段形成的关pȝ的访问?br />
• getFragments(Bundle) – q回一个bundles的集合,q个集合中的bundles是给定bundle的片D,如果没有片段Q返回null
• getHosts(Bundle) – q回l定bundle的宿主bundle。这个给定的bundle应该是个片段Q否则返回null?br />
• getRequiredBundles(String) – q回RequiredBundle对象的集合,q个集合匚w了给定的名字Qbundle标记名)Q如果给定的名字是nullQ将q回所有required的bundles。每一个RequiredBundle对象提供了对一个required的bundle的结构信息的描述?
7.2.4 Exported Package
Information about the shared packages is provided by the ExportedPackage objects. These objects provide detailed information about the bundles that import and export the package. This information can be used by a Management Agent to guide its decisions.
与共享包相关的信息是由ExportedPackage对象提供的,q些ExportedPackage对象提供了引入包或输出包的bundles的细节信息,q些信息可以被Management Agent用于参考它的决定?
7.2.5 Refreshing Packages and Start Level Service
Bundles may be stopped and later started when the refreshPackages(Bundle[]) method is called. If the Start Level Service is present, the stopping and starting of bundles must not violate the start level constraints. This implies that bundles with a higher start level must be stopped before bundles with a lower start level are stopped. Vice versa, bundles should not be started
before all the bundles with a lower start level are started. See Startup Sequence on page 207.
当调用refreshPackages(Bundle[])ҎӞbundles可能会先停止Q然后又启动Q如果设|了启动U别服务Q那么bundles的停止和启动必须不能q反启动U别的限Ӟ也就是说高启动别的bundles必须比低启动U别的bundles先停止,低启动别的bundles比高启动U别的bundles先启动?br />
OSGi Service Layer定义了一个与Life Cycle Layer紧密l合的动态协作模型,服务模型是发布,查找和绑定模型。一个服务是一个普通的java对象Q在服务注册器中注册于一个或多个java接口之下。bundles可以注册服务(through its BundleContext)Q查找服务,或当服务的注册状态改变时得到通知?
5.1.1 Essentials
• Collaborative – The service layer must provide a mechanism for bundles to publish, find, and bind to each other’s services without having a priori knowledge of those bundles.
• Collaborative – 服务层必ȝbundles提供一个机制用于发布,查找和绑定其他各自bundles的服务,而不需要有q些bundles的先期知识?br />
• Dynamic – The service mechanism must be able to handle changes in the outside world and underlying structures directly.
• Dynamic – 服务机制必须能直接操作外部的和底层的改变?br />
• Secure – It must be possible to restrict access to services.
• Secure – 必须能限制服务的讉K?br />
• Reflective – Provide full access to the Service Layer’s internal state.
• Reflective – 提供Ҏ务层内部状态的完全讉K?br />
• Versioning – Provide mechanisms that make it possible to handle the fact that bundles and their services evolve over time.
• Versioning – 提供机制Q其能够操作bundle和它们的服务的变?br />
• Persistent Identifier – Provide a means for bundles to track services across Framework restarts.
• Persistent Identifier –提供一个方法时bundles能跟t服务不受框枉启的影响?br />
5.1.2 Entities
• Service – An object registered with the service registry under one or more interfaces together with properties. This object can be discovered and used by bundles.
• Service – 一个对象,在服务注册器中注册于一个或多个接口的名下,服务可以有属性,q个对象可以被bundles发现q用?br />
• Service Registry – Holds the service registrations.
• Service Registry – 服务注册器,保存服务暂住?br />
• Service Reference – A reference to a service. Provides access to the service’s properties but not the actual service object. The service object must be acquired through a bundle’s Bundle Context.
• Service Reference – C个服务的引用。提供了对这个服务的属性的讉KQ但是ƈ不是真正的服务对象,真正的服务对象必通过bundle的BundleContext对象获得?br />
• Service Registration – The receipt provided when a service is registered. The service registration allows the update of the service properties and the unregistration of the service.
• Service Registration – 一个暂住证Q意思是收到一个服务的注册Q而且注册在q个证里Q,服务暂住证允许服务属性的更新和注销服务?br />
• Service Permission – The permission to use an interface name when registering or using a service.
• Service Permission – 一个权限用于当注册或用一个服务时使用一个接口名字?br />
• Service Factory – A facility to let the registering bundle customize the service object for each using bundle.
• Service Factory – 一个灵zȝ工具Q注册服务的bundle为每一个要使用q个服务的bundle定制服务对象?br />
• Service Listener – A listener to Service Events.
• Service Event – An event holding information about the registration, modification, or unregistration of a service object.
• Filter – An object that implements a simple but powerful filter language. It can select on properties.
• Invalid Syntax Exception – The exception thrown when a filter expression contains an error.
5.2 Services
In the OSGi Service Platform, bundles are built around a set of cooperating services available from a shared service registry. Such an OSGi service is defined semantically by its service interface and implemented as a service object.
在OSGi服务q_中,bundles从一个共享服务注册器中徏造一l可怺协作的服务,q样一个OSGi服务通过它的服务接口来定义的Qƈ被实Cؓ一个服务对象?br />
The service interface should be specified with as few implementation details as possible. OSGi has specified many service interfaces for common needs and will specify more in the future.
服务接口应该可能少的指定实现细节,OSGi已经为通用需求指定了很多服务接口Q以后会更多?br />
The service object is owned by, and runs within, a bundle. This bundle must register the service object with the Framework service registry so that the service’s functionality is available to other bundles under control of the Framework.
服务对象属于一个bundleQƈ在bundle中运行,bundle必须这个服务对象注册到框架服务注册器中Q以便在框架的控制下Q这个服务的功能可以被其他bundles使用?br />
Dependencies between the bundle owning the service and the bundles using it are managed by the Framework. For example, when a bundle is stopped, all the services registered with the Framework by that bundle must be automatically unregistered.
提供服务的bundle和用服务的bundle之间的依赖关pȝ框架来管理。例如,当一个bundle停止后,所有这个bundle注册到框架的服务必须自动注销Q由框架来注销Q?br />
The Framework maps services to their underlying service objects, and provides a simple but powerful query mechanism that enables a bundle to request the services it needs. The Framework also provides an event mechanism so that bundles can receive events of services that are registered, modified, or unregistered.
框架服务映到它们的服务对象,q提供一个简单而强大的查询机制Q一个bundleh一个它需要的服务。框枉提供了一个事件机制以便bundles能接收服务注册,修改或注销的事件?br />
5.2.1 Service References
In general, registered services are referenced through ServiceReference objects. This avoids creating unnecessary dynamic service dependencies between bundles when a bundle needs to know about a service but does not require the service object itself.
通常Q注册的服务通过ServiceReference对象d用它Q这避免了当一个bundle需要知道一个服务但是不需要这个服务对象本w时Q创Z个不必要的bundles之间的动态服务依赖关pR?br />
A ServiceReference object can be stored and passed on to other bundles without the implications of dependencies. When a bundle wishes to use the service, it can be obtained by passing the ServiceReference object to BundleContext.getService(ServiceReference). See Locating Services on
page 114.
一个ServiceReference 对象可以被保存ƈ传到别的bundlesQ而不需要实C赖关pR当一个bundle想用这个服务时Q它能通过ServiceReference 对象传到BundleContext.getService(ServiceReference)来获?br />
A ServiceReference object encapsulates the properties and other metainformation about the service object it represents. This meta-information can be queried by a bundle to assist in the selection of a service that best suits its needs.
When a bundle queries the Framework service registry for services, the Framework must provide the requesting bundle with the ServiceReference objects of the requested services, rather than with the services themselves.
当一个bundle在框架服务注册器中查询服务时Q框架必ȝq个查询bundle提供它请求的服务的ServiceReference对象Q而不是这些服务本w?br />
A ServiceReference object may also be obtained from a ServiceRegistration object.
一个ServiceReference对象也可以从ServiceRegistration对象那获得?br />
A ServiceReference object is valid only as long as the service object is registered. However, its properties must remain available as long as the ServiceReference object exists.
ServiceReference对象仅仅只在服务对象被注册时可以使用Q但是它的属性会一直可用只要ServiceReferenc对象存在?
5.2.2 Service Interfaces
A service interface is the specification of the service’s public methods. In practice, a bundle developer creates a service object by implementing its service interface and registers the service with the Framework service registry. Once a bundle has registered a service object under an interface name, the associated service can be acquired by bundles under that interface name,
and its methods can be accessed by way of its service interface. The Framework also supports registering service objects under a class name, so references to service interface in this specification can be interpreted to be an interface or class.
一个服务接口是服务的公共方法的规范Q在实际应用中,一个bundle开发者通过实现服务接口来创Z个服务对象,q将q个服务注册到框架服务注册器中。一旦一个bundle以一个接口名注册了一个服务对象,q个兌的服务就能在bundles中通过接口名获得,它的Ҏ能以它的服务接口的方式访问。框枉支持以类名的方式注册服务Q所以规范中的服务接口可以被理解Z个接口或一个类(当然一般情况下都是用接??br />
When requesting a service object from the Framework, a bundle can specify the name of the service interface that the requested service object must implement. In the request, the bundle may also specify a filter string to narrow the search.
当一个bundle从框架中h一个服务对象时Q它能指定那个被h的服务对象必d现的服务接口的名字,hq程中,bundle也可以指定一个过滤器字符串来~小查找范围?br />
Many service interfaces are defined and specified by organizations such as the OSGi Alliance. A service interface that has been accepted as a standard can be implemented and used by any number of bundle developers.
很多服务接口被OSGi联盟q样的组l定义和指定了,一个被公认为标准的服务接口可以被bundle开发者实现ƈ使用?br />
例如Q?参见org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider)
bundleContext.getServiceReference("org.osgi.service.packageadmin.PackageAdmin");
5.2.3 Registering Services
A bundle publishes a service by registering a service object with the Framework service registry. A service object registered with the Framework is exposed to other bundles installed in the OSGi environment.
一个bundle通过一个服务对象注册到框架服务注册器来发布一个服务,一个被注册的服务对象被暴露l其他安装了的bundles?br />
Every registered service object has a unique ServiceRegistration object, and has one or more ServiceReference objects that refer to it. These ServiceReference objects expose the registration properties of the service object, including the set of service interfaces they implement. The ServiceReference object can then be used to acquire a service object that
implements the desired service interface. The Framework permits bundles to register and unregister service objects dynamically. Therefore, a bundle is permitted to register service objects at any time during the STARTING, ACTIVE or STOPPING states.
每个注册的服务对象都有一个唯一的ServiceRegistration对象Qƈ且有一个或多个ServiceReference对象引用它,q些ServiceReference对象暴露服务对象的注册属性,包括它们实现的服务接口,然后可以使用ServiceReference对象来获取实C服务接口的服务对象。框架允许bundle动态地注册和注销服务对象Q因此一个bundle可以在STARTING,ACTIVE或STOPPING状态注册服务对象?br />
A bundle registers a service object with the Framework by calling one of the BundleContext.registerService methods on its BundleContext object:
• registerService(String,Object,Dictionary) – For a service object registered under a single service interface.
• registerService(String[],Object,Dictionary) – For a service object registered under multiple service interfaces.
一个bundle可以通过调用以下Ҏ注册服务对象Q?br />
• registerService(String,Object,Dictionary) – 一个服务对象注册到一个服务接口名?br />
• registerService(String[],Object,Dictionary) –一个服务对象注册到多个服务接口名下
The names of the service interfaces under which a bundle wants to register its service are provided as arguments to the registerService methods. The Framework must ensure that the service object actually is an instance of each specified service interfaces, unless the object is a Service Factory. See Service Factory on page 117.
一个bundle注册它的服务Q一个对象)C个(些)服务接口Q这个(些)服务接口的名字做为参数提供给registerServiceҎ。框架必ȝ保服务对象是q些服务接口的实例,除非q个服务对象是一个ServiceFactory
To perform this check, the Framework must load the Class object for each specified service interface from either the bundle or a shared package. For each Class object, Class.isInstance must be called and return true on the Class object with the service object as the argument.
对于执行q个查,框架必须些来自bundle或共享包的服务接口加载Class对象Q调用Class.isInstanceҎQ服务对象作为参敎ͼ必须q回true
The service object being registered may be further described by a Dictionary object, which contains the properties of the service as a collection of key/value pairs.
被注册的服务对象后面的一个被Dictionary对象描述的参敎ͼ可能包含了将服务的属性做Z个键值对集合?br />
The service interface names under which a service object has been successfully registered are automatically added to the service object’s properties under the key objectClass. This value must be set automatically by the Framework and any value provided by the bundle must be overridden.
一个服务对象被成功注册于服务接口的名下Q这个(些)接口的名字会被自动添加到服务对象的属性中Q键名ؓobjectClass(gؓ字符串数l类?。这些值必ȝ框架自动dQbundle提供的值必被覆盖?br />
If the service object is successfully registered, the Framework must return a ServiceRegistration object to the caller. A service object can be unregistered only by the holder of its ServiceRegistration object (see the unregister() method). Every successful service object registration must yield a unique ServiceRegistration object even if the same service object is registered multiple times.
如果服务对象被成功注册,框架必须q回一个ServiceRegistration对象l调用者。一个服务对象仅仅只能被持有它的ServiceRegistration对象注销。每一ơ服务对象的成功注册都要伴随生成一个ServiceRegistration对象Q即使一个相同的服务对象已经被注册过了?br />
5.2.4 Early Need for ServiceRegistration Object
The registration of a service object will cause all registered ServiceListener objects to be notified. This is a synchronous notification. This means that such a listener can get access to the service and call its methods before the registerService method has returned the ServiceRegistration object. In certain cases, access to the ServiceRegistration object is necessary in such a callback. However, the registering bundle has not yet received the
ServiceRegistration object. Figure 5.30 on page 111 shows such a sequence.
一个服务对象的注册会所有注册的ServiceListener对象得到通知Q有服务被注册了Q,q是一个同步通知Q这意味着一个监听器能在registerServiceҎq回ServiceRegistration对象之前讉K服务q调用服务的Ҏ。在某些情况下,在这L回调Ҏ中访问ServiceRegistration对象是有必要的,但是注册服务的bundle此时q没有收到ServiceRegistration对象?br />
In a case as described previously, access to the registration object can be obtained via a ServiceFactory object. If a ServiceFactory object is registered, the Framework must call-back the registering bundle with the ServiceFactory method getService(Bundle,ServiceRegistration). The required ServiceRegistration object is passed as a parameter to this method.
在前面描q的例子中,可以通过ServiceFactory对象来访问注册对象,如果一个ServiceFactory对象被注册,框架必须以ServiceFactory.getService(Bundle,ServiceRegistration)Ҏ回调注册bundle。ServiceRegistration对象做ؓ参数传入q个Ҏ中?
5.2.5 Service Properties
Properties hold information as key/value pairs. The key must be a String object and the value should be a type recognized by Filter objects (see Filters on page 116 for a list). Multiple values for the same key are supported with arrays ([]) and Collection objects.
The values of properties should be limited to primitive or standard Java types to prevent unwanted inter bundle dependencies. The Framework cannot detect dependencies that are created by the exchange of objects between bundles via the service properties.
The key of a property is not case sensitive. ObjectClass, OBJECTCLASS and objectclass all are the same property key. A Framework must return the key in ServiceReference.getPropertyKeys in exactly the same case as it was last set. When a Dictionary object that contains keys that only differ in case is passed, the Framework must raise an exception.
The service properties are intended to provide information about the service object. The properties should not be used to participate in the actual function of the service. Modifying the properties for the service registration is a potentially expensive operation. For example, a Framework may pre-process the properties into an index during registration to speed up later lookups.
The Filter interface supports complex filtering; it can be used to find matching service objects. Therefore, all properties share a single name space in the Framework service registry. As a result, it is important to use descriptive names or formal definitions of shorter names to prevent conflicts. Several OSGi specifications reserve parts of this name space. All properties starting with the prefix service. and the property objectClass are reserved for use by
OSGi specifications.
Table 5.9 Standard Service Properties contains a list of pre-defined properties.
Table 5.9 Standard Service Properties
Property Key
Type
Constants
Property Description
service.id
Long
SERVICE_ID
Every registered service object is
assigned a unique service.id by the
Framework. This number is added
to the service object’s properties.
The Framework assigns a unique
value to every registered service
object that is larger than values provided
to all previously registered
service objects.
service.pid
String
SERVICE_PID
The service.pid property optionally
identifies a persistent, unique
identifier for the service object. See
Persistent Identifier (PID) on page
113.
service.ranking
Integer
SERVICE_RANKING
When registering a service object, a
bundle may optionally specify a
service.ranking number as one of
the service object’s properties. If
multiple qualifying service interfaces
exist, a service with the highest
SERVICE_RANKING number, or
when equal to the lowest
SERVICE_ID, determines which service
object is returned by the Framework.
service.vendor
String
SERVICE_VENDOR
This optional property can be used
by the bundle registering the service
object to indicate the vendor.
5.2.6 Persistent Identifier (PID)
The purpose of a Persistent Identifier (PID) is to identify a service across Framework restarts. Services that can reference the same underlying entity every time they are registered should therefore use a service property that contains a PID. The name of the service property for PID is defined as service.pid. The PID is a unique identifier for a service that persists over
multiple invocations of the Framework. For a given service, the same PID should always be used. If the bundle is stopped and later started, the same PID must always be used.
The format of the PID should be:
A PID must be unique for each service. A bundle must not register multiple services with the same PID, nor should other bundles use the same PID. If this happens, it is an error condition.
Persistent Identifier (PID)的目的是Z在框枉启后识别一个服务,每次服务注册Ӟ都引用同一个实体,因此应当使用一个包含了PID的服务属性。服务属性的名字被定义ؓservice.pid?br />
5.2.7 Locating Services
In order to use a service object and call its methods, a bundle must first obtain a ServiceReference object. The BundleContext interface defines two methods a bundle can call to obtain ServiceReference objects from the Framework:
Z使用一个服务对象ƈ调用它的ҎQ一个bundle必须首先获得一个ServiceReference对象。接口BundleContext定义?个方法来从框架中获取ServiceReference对象Q?br />
• getServiceReference(String) – This method returns a ServiceReference object to a service object that implements, and was registered under, the name of the service interface specified as String. If multiple such service objects exist, the service object with the highest SERVICE_RANKING is returned. If there is a tie in ranking, the service object with the lowest
SERVICE_ID (the service object that was registered first) is returned.
• getServiceReference(String) – q个Ҏq回一个到一个服务对象的ServiceReference对象Q这个服务对象实现ƈ注册于参CString指定的服务接口,如果有多个这L服务对象存在Q具有最高SERVICE_RANKING的服务对象被q回。如果有2个相同的SERVICE_RANKINGQ那么具有最低SERVICE_ID(先被安装?的服务对象被q回?br />
• getServiceReferences(String,String) – This method returns an array of ServiceReference objects that:
• Implement and were registered under the given service interface.
• Satisfy the search filter specified. The filter syntax is further explained in Filters on page 116.
Both methods must return null if no matching service objects are returned. Otherwise, the caller receives one or more ServiceReference objects. These objects can be used to retrieve properties of the underlying service object, or they can be used to obtain the actual service object via the BundleContext object.
如果没有匚w的服务对象,q两个方法必返回nullQ否则,调用者将收到1个或多个ServiceReference对象。这些对象能被用来获取服务对象属性,或是通过BundleContext来获取真正的服务对象?br />
Both methods require that the caller has the required ServicePermission[<name>, GET] to get the service object for the specified service interface names. If the caller lacks the required permission, these methods must return null.
q两个方法需要调用者有ServicePermission[<name>, GET]权限通过制定的服务接口名去获得服务对象,如果调用者没有这个权限,q两个方法必返回null?
5.2.8 Getting Service Properties
To allow for interrogation of service objects, the ServiceReference interface defines these two methods:
• getPropertyKeys() – Returns an array of the property keys that are available.
• getProperty(String) – Returns the value of a property.
Both of these methods must continue to provide information about the referenced service object, even after it has been unregistered from the Framework. This requirement can be useful when a ServiceReference object is stored with the Log Service.
5.2.9 Getting Service Objects
The BundleContext object is used to obtain the actual service object so that the Framework can manage dependencies. If a bundle retrieves a service object, that bundle becomes dependent upon the life cycle of that registered service object. This dependency is tracked by the BundleContext object used to obtain the service object, and is one reason that it is important to be careful when sharing BundleContext objects with other bundles.
BundleContext对象用于获取真实的服务对象,因此框架要管理它们的依赖关系。如果一个bundle获得了一个服务对象,那么q个bundle依赖于那个注册的服务对象的生命周期Q这个依赖关pȝ用于获取服务对象的BundleContext去跟t,q样做的原因是防止bundles间共享BundleContext?br />
The method BundleContext.getService(ServiceReference) returns an object that implements the interfaces as defined by the objectClass property.
ҎBundleContext.getService(ServiceReference)q回一个实C属性中"objectClass"指定接口的对象?br />
This method has the following characteristics:
q个Ҏ有以下特性:
• Returns null if the underlying service object has been unregistered.
• 如果服务对象已经被注销Q返回null
• Determines if the caller has ServicePermission[<interface name>,GET], to get the service object using at least one of the service interfaces under which the service was registered. This permission check is necessary so that ServiceReference objects can be passed around freely without compromising security.
• 军_调用者是否有ServicePermission[<interface name>,GET]权限使用臛_其中一个服务接口去得到一个注册于该服务接口名下的服务对象。这个检查是有必要的Q这h能ServiceReference对象自由传递而不需要考虑安全问题?br />
• Increments the usage count of the service object by one for this BundleContext object.
• q个BundleContext对象使用q个服务对象的次数加1.
• If the service object does not implement the ServiceFactory interface, it is returned. Otherwise, if the bundle context’s usage count of the service object is one, the object is cast to a ServiceFactory object and the getService method is called to create a customized service object for the calling bundle which is then returned. Otherwise, a cached copy of this
customized object is returned. See Service Factory on page 117 for more information about ServiceFactory objects.
• 如果服务对象没有实现ServiceFactory接口Q它直接被返回。否则,如果bundlecontext使用q个服务对象的次数是1Q这个对象将被castZ个ServiceFactory对象QgetServiceҎ被调用来用bundle生成一个定制的服务对象Q如果次C?Q一个缓存的定制对象被返回?
5.2.10 Information About Services
The Bundle interface defines these two methods for returning information pertaining to service usage of the bundles:
接口Bundle定义?个方法用于返回bundles使用的服务的相关信息
• getRegisteredServices() – Returns the service objects that the bundle has registered with the Framework.
• getRegisteredServices() – q回bundle已经注册的服务对象?br />
• getServicesInUse() – Returns the service objects that the bundle is using.
• getServicesInUse() – q回bundle使用的服务对象?br />
5.3 Service Events
• ServiceEvent – Reports registration, unregistration, and property changes for service objects. All events of this kind must be delivered synchronously. The type of the event is given by the getType() method, which returns an int. Event types can be extended in the future;
unknown event types should be ignored.
• ServiceListener – Called with a ServiceEvent when a service object has been registered or modified, or is in the process of unregistering. A security check must be performed for each registered listener when a ServiceEvent occurs. The listener must not be called unless the bundle which registered the listener has the required ServicePermission[<interface name>,GET] for at least one of the interfaces under which the service object is registered.
• ServiceEvent – 报告服务对象的注册,注销和属性改变,所有这个类型的事g必须被同步发送。事件的cd通过getType()Ҏ获得Q返回的是一个int。事件类型可以被扩展Q未知的旉cd应该被忽略?br />
• ServiceListener –附带一个ServiceEvent做ؓ参数被调用于一个服务对象被注册或改变,或是在注销Ӟ
。当一个ServiceEvent发生Ӟ必须为每一个注册的监听器执行安全检查,如果监听器对一个服务接口没有ServicePermission[<interface name>,GET]权限Q监听器必须不能被调用?br />
A bundle that uses a service object should register a ServiceListener object to track the availability of the service object, and take appropriate action when the service object is unregistering.
一个用服务对象的bundle应该注册一个ServiceListener对象来跟t这个服务对象的有效性,在服务对象注销旉取合适的处理?br />
5.4 Stale References
The Framework must manage the dependencies between bundles. This management is, however, restricted to Framework structures. Bundles must listen to events generated by the Framework to clean up and remove stale references.
框架必须理bundles间的依赖关系Q但是这个管理限制于框架l构。bundles必须监听框架生成的事Ӟ清理和移除失效的引用?br />
A stale reference is a reference to a Java object that belongs to the class loader of a bundle that is stopped or is associated with a service object that is unregistered. Standard Java does not provide any generic means to clean up stale references, and bundle developers must analyze their code carefully to ensure that stale references are deleted.
一个失效的引用是指Q引用了一个属于停止了的bundle的classloader或是兌了一个已l注销了的java对象。标准java没有提供一个通用ҎL理失效的引用Qbundle开发者必Ml分析代码以保失效的引用被删除?br />
Stale references are potentially harmful because they hinder the Java garbage collector from harvesting the classes, and possibly the instances, of stopped bundles. This may result in significantly increased memory usage and can cause updating native code libraries to fail. Bundles using services are strongly recommended to use either the Service Tracker or Declarative
Services.
失效的引用是一个潜在的危险Q因为它们妨了java gc回收停止了的bundles的对象实例,q可能导致增加内存的使用和引hC码库更新p|。对于bundle使用servicesQ强烈推荐用Service Tracker或Declarative Services?br />
Service developers can minimize the consequences of (but not completely prevent) stale references by using the following mechanisms:
• Implement service objects using the ServiceFactory interface. The methods in the ServiceFactory interface simplify tracking bundles that use their service objects. See Service Factory on page 117.
• Use indirection in the service object implementations. Service objects handed out to other bundles should use a pointer to the actual service object implementation. When the service object becomes invalid, the pointer is set to null, effectively removing the reference to the actual service object.
服务开发者可以用以下机制来可能的减少失效的引?
• 服务对象实现ServiceFactory接口Q接口ServiceFactory中的Ҏ化了对用服务对象的bundles的跟t?br />
• 使用介引用服务对象的实现。bundles注册的服务应该用一个指针指向真是的服务对象的实玎ͼ当服务对象不可用Ӟq个指针讄为nullQ有效的U除对真实服务对象的引用?br />
The behavior of a service that becomes unregistered is undefined. Such services may continue to work properly or throw an exception at their discretion. This type of error should be logged.
一个服务注销的行为没有定义,q些服务可能会l工作或是随意抛Z个exceptionQ错误类型应该被记录?br />
5.5 Filters
The Framework provides a Filter interface, and uses a filter syntax in the getServiceReferences method that is defined in Filter Syntax on page 29. Filter objects can be created by calling BundleContext.createFilter(String) or FrameworkUtil.createFilter(String) with the chosen filter string. The filter supports the following match methods:
• match(ServiceReference) – Match the properties of the Service Reference performing key lookup in a case insensitive way.
• match(Dictionary) – Match the entries in the given Dictionary object performing key lookup in a case insensitive way.
• matchCase(Dictionary) – Match the entries in the given Dictionary object performing key lookup in a case sensitive way.
框架提供了一个Filter接口Qƈ在方法getServiceReferences 中用了一个过滤器(filter)语法QFilter 对象可以通过调用BundleContext.createFilter(String)或FrameworkUtil.createFilter(String)以一个过滤器字符串ؓ参数来创建。filter 支持以下匚wҎQ?br />
• match(ServiceReference) – 匚wServiceReference的属性,不区分大写
• match(Dictionary) – 匚wl定的Dictionary 对象实体Q不区分大小?br />
• matchCase(Dictionary) – 匚wl定的Dictionary 对象实体Q区分大写
A Filter object can be used numerous times to determine if the match argument, a ServiceReference object or a Dictionary object, matches the filter string that was used to create the Filter object.
一个Filter对象可以无限使用于决定参数ServiceReference 对象或Dictionary 对象是否匚w创徏Filter对象时的qo器字W串?br />
This matching requires comparing the value string in the filter to a target object from the service properties or dictionary. This comparison can be executed with the Comparable interface if the target object’s class implements a constructor taking a single String object and the class implements the Comparable interface. That is, if the target object is of class Target, the class Target must implement:
• A constructor Target(String)
• Implement the java.lang.Comparable interface
q个匚w需要在qo器中比对一个目标对象中的字W串g服务属性或字典对象中的字符串|如果目标对象实现了接口Comparableq有以一个String对象为参数的构造函敎ͼ可以使用Comparable来执行比?br />
If the target object does not implement java.lang.Comparable, the =, ~=, <=, >= operators must return only true when the objects are equal (using the equals(Object) method). The Target class does not need to be a public class.
如果目标对象没有实现Comparable接口Q?, ~=, <=, >= 操作只有?个对象相{?使用equals(Object) Ҏ)的时候才q回true
The following example shows how a class can verify the ordering of an enumeration with a filter.
String keys[] = {"bugs", "daffy", "elmer", "pepe"};
int index;
public B(String s) {
for ( index=0; index<keys.length; index++ )
if ( keys[index].equals(s) )
return;
}
public int compareTo( Object other ) {
B vother = (B) other;
return index - vother.index;
}
}
The class could be used with the following filter: (!(enum>=elmer)) -> matches bugs and daffy
The Filter.toString method must always return the filter string with unnecessary white space removed.
5.6 Service Factory
A Service Factory allows customization of the service object that is returned when a bundle calls BundleContext.getService(ServiceReference).
当一个bundle调用BundleContext.getService(ServiceReference)ҎӞServiceFactory允许q回的是一个定制的服务对象?br />
Often, the service object that is registered by a bundle is returned directly. If, however, the service object that is registered implements the ServiceFactory interface, the Framework must call methods on this object to create a unique service object for each distinct bundle that gets the service.
通常Q由一个bundle注册的服务对象会直接q回。但是如果这个服务对象实CServiceFactory接口Q框架必调用这个对象中的方法来为各个不同的bundle创徏一个唯一的服务对象?br />
When the service object is no longer used by a bundle – for example, when that bundle is stopped – then the Framework must notify the ServiceFactory object.
当服务对象不再被bundle使用?- 例如Q当bundle停止?- 框架必须通知ServiceFactory对象?br />
ServiceFactory objects help manage bundle dependencies that are not explicitly managed by the Framework. By binding a returned service object to the requesting bundle, the service can be notified when that bundle ceases to use the service, such as when it is stopped, and release resources associated with providing the service to that bundle.
ServiceFactory对象帮助理那些框架q不明确理的bundle的依赖关p(例如服务注册引发的依赖关p)Q通过一个服务对象绑定到注册它的bundleQ这个服务会在bundlel止使用它时得到通知Q例如当bundle停止Qƈ释放与服务相兌的资源时?br />
The ServiceFactory interface defines the following methods:
接口ServiceFactory定义了以下方法:
• getService(Bundle,ServiceRegistration) – This method is called by the Framework if a call is made to BundleContext.getService and the following are true:
• getService(Bundle,ServiceRegistration) – 如果是通过BundleContext.getService调用Qƈ满以下条gQ这个方法将被框架调用来q回一个服务对?br />
• The ServiceReference argument to BundleContext.getService refers to a service object that implements the ServiceFactory interface.
• BundleContext.getService中的参数ServiceReference对象引用的服务对象实C接口ServiceFactory
• The bundle’s usage count of that service object is zero; that is, the bundle currently does not have any dependencies on the service object.
• bundle中的q个服务对象的用次数是0Q也是说目前这个bundle对这个服务对象还没有M依赖关系?br />
The call to BundleContext.getService must be routed by the Framework to this method, passing to it the Bundle object of the caller. The Framework must cache the mapping of the requesting bundle-to-service, and return the cached service object to the bundle on future calls to
BundleContext.getService, as long as the requesting bundle's usage count of the service object is greater than zero. The Framework must check the service object returned by this method. If it is not an instance of all the classes named when the service factory was registered, null is returned to the caller that called getService. This check must be done as specified in Registering Services on page 110.
如果以上条g成立Q框架必d对BundleContext.getService的调用\由到q个ҎQServiceFactory.getService(Bundle,ServiceRegistration)Q,调用者的Bundle对象传入。框架必ȝ存bundleҎ务的h的映关p,当下ơ这个bundle再次hq个服务Ӟ直接q回~存中的服务对象Qƈ且要使请求的bundle对这个服务的使用ơ数大于0.框架必须查这个方法返回的服务对象Q如果这个对?实现了ServiceFactory接口)不是注册它时所指定的类?q个cd可以是接口,也可以是具体c?的实例,必须q回null?br />
• ungetService(Bundle,ServiceRegistration,Object) – This method is called by the Framework if a call is made to BundleContext.ungetService and the following are true:
• ungetService(Bundle,ServiceRegistration,Object) – 如果是通过BundleContext.ungetService调用Qƈ满以下条gQ这个方法将被框架调?br />
• The ServiceReference argument to BundleContext.ungetService refers to a service object that implements the ServiceFactory interface.
• BundleContext.ungetService的参数ServiceReference对象引用的服务对象实CServiceFactory接口
• The bundle’s usage count for that service object must drop to zero after this call returns; that is, the bundle is about to release its last dependency on the service object.
• q个调用q回之后Qbundle对这个服务对象的使用ơ数减少?Q也是_bundle会释攑֮对这个服务对象的全部依赖关系?br />
The call to BundleContext.ungetService must be routed by the Framework to this method so the ServiceFactory object can release the service object previously created.
Additionally, the cached copy of the previously created service object must be unreferenced by the Framework so it may be garbage collected.
如果以上条g成立Q框架必d对BundleContext.ungetService 的调用\由到q个ҎQServiceFactory.ungetService(Bundle,ServiceRegistration)Q,使ServiceFactory对象能释放以前生成的服务对象?br />
另外Q以前生成的服务对象的缓存片嘟啊必须被框架解除引用,使之可以被gc
5.7 Releasing Services
In order for a bundle to release a service object, it must remove the dynamic dependency on the bundle that registered the service object. The BundleContext interface defines a method to release service objects: ungetService(ServiceReference). A ServiceReference object is passed as the argument of this method.
Z使一个bundle释放一个服务对象,它必ȝ除与注册了服务对象的bundle上的动态依赖关pR接口BundleContext定义了一个释放服务对象的ҎQungetService(ServiceReference)Q参数是一个ServiceReference对象?br />
This method returns a boolean value:
• false if the bundle’s usage count of the service object is already zero when the method was called, or the service object has already been unregistered.
• true if the bundle’s usage count of the service object was more than zero before this method was called.
q个Ҏq回一个boolean|
• false - 当这个方法被调用Ӟbundle中对服务对象的用次数是0Q或者服务对象已l被注销?br />
• true - q个Ҏ调用Ӟbundle中对服务对象的用次数大?
5.8 Unregistering Services
The ServiceRegistration interface defines the unregister() method to unregister the service object. This must remove the service object from the Framework service registry. The ServiceReference object for this ServiceRegistration object can no longer be used to access the service object.
ServiceRegistration接口定义了unregister()Ҏ用于注销服务对象Q这个方法必M框架的服务注册器中移除这个服务对象。ServiceRegistration对象的ServiceReference对象不再能用来讉K服务对象?br />
The fact that this method is on the ServiceRegistration object ensures that only the bundle holding this object can unregister the associated service object. The bundle that unregisters a service object, however, might not be the same bundle that registered it. As an example, the registering bundle could have passed the ServiceRegistration object to another bundle, endowing that bundle with the responsibility of unregistering the service object. Passing ServiceRegistration objects should be done with caution.
ServiceRegistration对象中的q个Ҏ实际上确保了只有持有q个对象的bundle能够注销q个兌着的服务对?注:之前提到不需要在Activator中手动注销服务Q因为服务的注销由框架管理,当Bundle停止Ӟ它的BundleContext会注销服务Q参见org.eclipse.osgi.framework.internal.core.BundleContextImpl.close)。注销一个服务的bundle可能不是注册它的那个bundleQ例如,注册服务的bundle可以ServiceRegistration对象传给别的bundleQ由那个bundle负责注销服务对象。传递ServiceRegistration对象应慎重?br />
After ServiceRegistration.unregister successfully completes, the service object must be:
ServiceRegistration.unregister成功完成后,服务对象必须Q?br />
• Completely removed from the Framework service registry. Therefore, ServiceReference objects obtained for that service object can no longer be used to access the service object. Calling BundleContext.getService method with the ServiceReference object must return null.
• 完全从框架服务注册器中移除,因此用于获取服务对象的ServiceReference对象无法再用来访问这个服务对象,BundleContext.getServiceҎq回null?br />
• Unregistered, even if other bundles had dependencies upon it. Bundles must be notified of the unregistration through the publishing of a ServiceEvent object of type ServiceEvent.UNREGISTERING. This event is sent synchronously in order to give bundles the opportunity to release the service object. After receiving an event of type ServiceEvent.UNREGISTERING, a bundle should release the service object and release any references it has to this object, so that the service object can be garbage collected by the Java VM.
• 被注销Q即使其他bundlesq在依赖它。bundles必须通过发布的类型ؓServiceEvent.UNREGISTERING的ServiceEvent对象得到通知。这个事件发送是同步的,以便bundles有机会释放服务对象。收到ServiceEvent.UNREGISTERING事g后,bundle应该释放服务对象q放这个服务对象对q个bundle的引?
• Released by all using bundles. For each bundle whose usage count for the service object remains greater than zero after all invoked ServiceListener objects have returned, the Framework must set the usage count to zero and release the service object.
• 被所有用它的bundles释放Q事仉知Q。在所有ServiceListener得到通知之后Q对于每个对q个服务对象的用次C然大?的bundleQ框架必释放服务对象,q将使用ơ数讄?.
5.9 Multiple Version Export Considerations
Allowing multiple bundles to export a package with a given name causes some complications for Framework implementers and bundle programmers: The class name no longer uniquely identifies the exported class. This affects the service registry and permission checking.
允许多个bundles输出一个包增加了框架实现和bundle开发者的复杂度,因ؓcd不再是输出类的唯一标识W,q会影响服务注册和权限检查?br />
5.9.1 Service Registry
Bundles must not be exposed to services for which there are conflicting class loaders. A bundle that gets a service should be able to expect that it can safely cast the service object to any of the associated interfaces or classes under which the service was registered and that it can access. NoClassCastExceptions should occur because those interfaces do not come from the same class loader. The service registry must therefore ensure that bundles can only see services that are not incompatible with them. A service is not incompatible with the bundle getting the service when that bundle is not wired to another source class loader for this interface package than the bundle registering the service. That is, it is either wired to the same source
class loader or it has no wire for that package at all.
在class loaders冲突的情况下Qbundles不能被暴露给服务。获取一个服务的bundle应该被认为是能安全的服务对象cast到关联的接口或类。如果接口和服务对象不是来自同一个class loaderQ应该抛出NoClassCastExceptions。因此服务注册器必须保bundles仅仅能看C之兼容的服务。当获取服务的bundle没有个接口连接到其他源class loaderӞ没有q接到其他bundleQ,一个服务与获取的服务的bundle兼容。也是_要嘛接口和服务对象连接到同一个源class loaderQ要嘛根本就不连接它们(无法获取服务对象Q?
It is paramount that bundles are not accidentally confronted with incompatible services. Therefore, the following methods need to filter ServiceReference objects depending on the incompatibility of the interfaces with the calling bundle. The bundle is identified by the used BundleContext:
• getServiceReference(String) – Only return a Service Reference that is not incompatible with the calling bundle for the specified interface.
• getServiceReferences(String,String) – Only return Service References that are not incompatible with the calling bundle for the specified interface.
有一点很重要Qbundlesl对不能意外的遇C兼容的服务,因此Q以下方法需要根据接口与调用bundle的兼Ҏ来qoServiceReference对象Q用BundleContext来识别bundle
• getServiceReference(String) – 仅仅q回一个ServiceReference对象Q它与调用bundle指定的接口兼?br />
• getServiceReferences(String,String) –q回多个ServiceReference对象?br />
The getAllServiceReferences(String,String) provides access to the service registry without any compatibility restrictions. Services acquired through this method can cause Class Cast Exceptions for the correct class names.
The ServiceReference isAssignableTo(Bundle,String) method is also available to test if the bundle that registered the service referenced by this ServiceReference and the specified bundle are both wired to same source for the specified interface.
5.9.2 Service Events
Service events must only be delivered to event listeners that are not incompatible with the Service Reference.
服务事g必须被发送到与ServiceReference兼容的事件监听器?br />
Some bundles need to listen to all service events regardless the compatibility issues. A new type of ServiceListener is therefore added: AllServiceListener. This is a marker interface; it extends ServiceListener. Listeners that use this marker interface indicate to the Framework that they want to see all services, including services that are incompatible with them.
一些bundles需要监听所有服务事件而不惛_心兼Ҏ问题,因此Q添加了一个新的对象类? AllServiceListener。这是一个标记接口,它承了ServiceListener。用这个标记接口的监听器表C它惌监听所有的服务Q包括那些不兼容的服务?br />
Last summer I received an invitation for IONA to attend the OSGi Enterprise Workshop on September 11, 2006. I believe I actually tried to find someone else to attend since it was the Monday following my vacation, and couldn't, so I ended up attending. One thing led to another – I recommended that IONA join OSGi to participate in the Enterprise Expert Group and I volunteered to co-chair it.
真正让OSGI引vx的是Eclipse,我觉得很多h对OSGI的认识还只是停留在这个层?Q?Eclipseq_是一个OSGI的实玎ͼq且下蝲和安装的每一个Eclipse plug实际上都使用了OSGI?br />
不过我想说这些认识是不够?Q?OSGI有一个简单的服务~程模块Q这个模块适应了当前面向服务编E的势Qƈ且支持动态部|Ԍq些功能在企业IT环境中会来被Z重视?/p>
EN: Absolutely, would make all the sense in the world. The bigger question is around the future of Java, and whether or not Sun will embrace OSGi or continue to fight it, and if they do continue to fight OSGi what impact that will have on Java. From my recent and somewhat limited experience with OSGi it seems that it significantly improves Java in many ways – modularity, versioning, improved class loading.
我完全同意,q将非常有意义。Sun是否接受OSGI甚至发展C之对立,如果是这P那么q个冲突会ljava带来什么?q是一个值得思考的问题。就我自己对OSGI的认识看来,OSGI会对JAVA带来很多q步Q例如模块化Q版本控制和cd载等?/p>
本文记录了将Spring Web Application应用到OSGI环境中,也就是OSGI Web应用?br />
[L击这里下载本文的Eclipse工程]
org.phrancol.osgi.demo.launcher工程中启动应用?br />
一、准备工?br />
1QJDK 1.5
2QEclipse 3.3-jee (MyEclipse)
3QSpring-framework-2.1-m3
4QSpring-osgi-1.0-m2
二、搭建环?/strong>
1Q首先当焉要一个Http ServerQ那qEclipse自带的Jetty吧?br />
2Q将Jetty和它的依赖包作ؓ Plugin 工程导入EclipseQ?nbsp; Import -> Plug-ins and fragments -> Next
3Q创Z个普通工E做为Eclipse Launch的存攄?org.phrancol.osgi.demo.launcher
4QOpen Run Dialog ... -> OSGI Framework -> New Configuration Q名字改为org.phrancol.osgi.demo.web.launcherQ在
Common面板Save as 里面?Shared file指定目录?org.phrancol.osgi.demo.launcher
注意依赖包关p?br />
启动后,在访?a href="http://localhost/shop/index.do">http://localhost/shop/index.do面Q报错,看来要解决一下标{ֺ问题Q在web目录中徏立一个WEB-INF目录Q将c.tld, fmt.tld拯q去Q然后在osgi控制台refresh springmvcQ再讉Kq个面Q发现没有图片,把jpetstore/images目录拯到web目录下,再refresh一下,OKQ首出来了?br />
六、结束语
q部分简单记录了如何使用springmvcQ下部分记录如何将jpetstore的各个层通过spring-osgi应用h
http://localhost/rspwebapp/platform/sp_redeploy 面重新部v插gQ然后再讉K http://localhost/rspwebappQ页面中多了
--------- Hello, Phrancol ! ---------
q?个Working set包含的内容:
Equinox - 单的_是OSGI的运行环境?br>Rsp samples - Web application的内容,包括配置文gQ资源文件等?br>Simplejars - Rsp samples里面所需要的Jar包,每个jar包都被作Z个独立的Plug-in.
五、Web application的目录结?br>org.rsp.sample.webapp实际上就是一个web应用Q可以在C:\rsp\apache-tomcat-5.5.15\conf\Catalina\localhost里面扑ֈContext的配|文件?br>在WebContent/WEB-INF/web.xml里面配置Equinox的servletbridge启动OSGIq行环境?br>q入C:\rsp\workspace\org.rsp.sample.webapp\WebContent\WEB-INF\platform目录Q发现里面的目录l构几乎与Eclipse的目录结构一P
q几个目录的用处:
configuration - 里面默认?config.ini 列出所有可用的bundleQ和他们的启动别,Equinox自动读取这个配|文件启动bundles
plugins - bundle都放在这里面
links - 与Eclipse里面的links目录作用一Pd外部bundle
Eclipse的网站上有Equinox更详l的介绍和简单的CZ [点击q里]
注意Q这个示例中使用的Equinox应该是较老的版本Q最新的版本对目录结构和bridge实现都有更好的改q,可以在Eclipse的CVS上获取最新的Equinox代码
六、访问其他bundle
打开org.rsp.sample.webapp/WebContent/struts.jspQ能看到<c:import url="/platform/do/myAct" />Q也是http://localhost/rspwebapp/platform/do/myAct Q这个页面是?org.rsp.framework.struts 提供的,打开它里面的 plugin.xmlQ可以发?br>q样一D配|?br>
<extension id="myservletID" name="myservletName" point="org.eclipse.equinox.servlet.ext.servlets">
<alias>/do</alias>
<servlet-class>org.rsp.framework.struts.base.BundleActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>*/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>chainConfig</param-name>
<param-value>*/WEB-INF/chain-config.xml</param-value>
</init-param>
<httpcontext-name>cross-context</httpcontext-name>
</extension>
里面是关于 Extension ?Extension points 的相关配|,在Equinox上有更详l的介绍Q于是大概能理解q个面是如何来的了Q也大概能理解如何用其他bundle的资源?br>
l束?/span>
偶尔从Google上搜索到了这文章,感觉对像我这LOSGI初学者很有用Q于是将其意思整理了一下,帖在BLOG上,希望能对路过的OSGI爱好者有所帮助?br>如果x好的理解作者的意图Q徏议看原文?br>Ƣ迎大家通过邮箱osgi.phrancol@gmail.com与我讨论有关OSGI的话题?br>
Developing Eclipse/OSGi Web Applications Part 1
Developing Eclipse/OSGi Web Applications Part 2
Equinox in a Servlet Container