|
Page Edited :
FELIX :
Apache Felix OSGi FAQ
Apache Felix OSGi FAQ has been edited by Richard S. Hall (Jun 24, 2008). Content:Apache Felix OSGi Frequently Asked QuestionsWhen I update my bundle, why are my bundle's old classes still being used?Updating a bundle does not necessarily cause the new classes to be used immediately, it depends on the status of your bundle. There are two possible situations:
A dependency among bundles occurs when one bundle imports (i.e., Import-Package or DynamicImport-Package) a package from another bundle or requires (i.e., Require-Bundle) another bundle. In case (1), the updated classes will become available immediately since no other bundles depend on the old version of the classes. Case (1) also applies to bundles that do not export at all, since it would be impossible for other bundles to depend on them. In case (2), the classes will not become immediately available since there are existing bundles that depend on the old version of the classes. In this cases, the new classes will not be made available until PackageAdmin.refreshPackages() is called (this can be invoked in the Felix shell using the refresh command). There is only one exception to case (2) where the exporting bundle does not also import its exported packages (see Should a bundle import its own exported packages? below for more information on this topic). In this case, the new classes become immediately accessible to the updated exporting bundle, but not to the dependent bundles; they continue to see the old version of the classes. This situation will still generally require PackageAdmin.refreshPackages() to be invoked to bring the bundles back to a useful state. This is the normal update process as defined by the OSGi specification. Updating a bundle is a two-step process, where older versions of exported packages are kept around until explicitly refreshed. This is done to reduce disruption when performing several updates. Should a service provider/consumer bundle be packaged with its service API packages?There is no easy answer to this question and it largely depends on the specific usage scenario. The OSGi specification had originally suggested that it was good practice to embed service API packages in the service provider bundle. In this case in OSGi R4, the service provider should both export and import the service API packages, which was the default for previous versions of the OSGi specification. The OSGi specification never had an explicit stance on whether or not a consumer bundle should embed its dependent service API packages; although, it would not appear to be a best practice. Logically, there is some sense to this approach, since it potentially allows the consumer bundle to gracefully handle broken service dependencies. Of course, this depends on whether there is anything the bundle can do in the face of broken dependencies. If service API packages are embedded in the consumer bundle, then it should export and import the packages. An alternative approach in this case is to dynamically import the service API (or even use optional imports if the dependency should only be considered once). The main advantages of embedding service API packages in bundles are that the dependencies can always be resolved and it does not require installing a lot of other bundles to resolve the dependencies. There are disadvantages, however. One disadvantage is resource consumption caused by potential code duplication. Probably a more serious disadvantage is that it makes it harder to dynamically swap out providers. For example, assume a provider bundle is used to export service API packages and all consumers are wired to that bundle. If the provider bundle is updated or uninstalled and then refreshed, then all consumer bundles will be stopped and refreshed as well. Even without a refresh, such a configuration would potentially inhibit garbage collection of the class loader of the service provider, since consumers would be using it for the API package. This situation would be different if the service API were package in a separate bundle. In this situation, all consumer bundles would be wired to the API bundle, not to the provider bundle. Thus, if the provider were updated or uninstalled and then refreshed, the consumer bundles would only be minimally impacted (i.e., they would either switch to the new version of the provider or to a different provider). Should a bundle import its own exported packages?In OSGi R3 this was always the case, since Export-Package implied Import-Package. It was a good idea then and is generally a good idea now. The whole point is substitutability of providers. If you import the packages you export, then the framework is free to choose a different provider of those packages for your bundle at resolve time, which means that your exports may go unused. However, this is a good thing, because the framework tries to minimize the number of active versions of a given package. The reason why this is a good thing is because it allows for higher levels of bundle interoperability. The more versions of a given package that are in use at any given time can lead to conflicts when trying to resolve bundle package dependencies and this also leads to partitioning of the service registry, since bundles can only see a single version of a given service package. If your bundle only exports its packages, then it is forcing the framework to wire itself to its own version, which will result in more active versions of the given package and thus less interoperability. The main time you want to export only, is if your bundle is purely a library bundle, then its packages will only be used if they are needed. Another case might be if you have tightly coupled bundles sharing implementation packages. However, if your bundle will be started and especially if the exported packages define service interfaces or are referenced from service interfaces, then you will generally want to export and import them. Why is my bundle not able to see annotations at run time?This is typically a class loading issue. At runtime the JVM will only return annotations that are visible to the current class loader, so if your bundle doesn't import the appropriate package(s) then you won't see them. This is not a bug, as such, it is simply how OSGi class loading works - your bundle cannot see classes that its hasn't imported (or acquired via Require-Bundle). It is also part of the design of annotations, since annotated classes are supposed to continue to load and resolve even if their annotation types aren't available on the class path. This lets you annotate a class with EJB3 annotations, for example, but also use it in a non-EJB container where you won't then see the EJB3 annotations. Try importing the annotation package inside your bundle to resolve the visibility issue. |
Unsubscribe or edit your notifications preferences
