I am trying to run OSGi framework (Equinox) in a main method.
Each time I start the framework, when I print BundleContext.getBundles().length, it says the framework has only 1 Bundle installed on (that is certainly the system bundle).
When I install my first bundle the bundle ID will continue from the last session. let's say if I had 4 bundles last session (and I have stopped and uninstalled all of them before stopping the system bundle), the first Bundle ID is set 5.
Now, I want to know how does the framework choose the bundle ID? Why and how does the framework remembers the last session, even though I had uninstalled all of the bundles? Is it because of Bundle Cache? And if it is, how can I clear the cache (to restart numbering from 1)?
The framework has the last used bundle id somewhere in the persistent store it manages. What this store looks like is a framework implementation detail. When you launch the framework, you can specify the org.osgi.framework.storage.clean framework configuration property. This will clear all installed bundles but I am not sure if it will reset the last used bundle id.
Deleting the equinox/org.eclipse.osgi folder resets the numbering. Before the delete make sure that your bundles don't have any important data under this folder.
The bundle command with a valid bundle id can show the absolute path of the equinox/org.eclipse.osgi folder:
osgi> bundle 7
slf4j.api_1.6.1 [7]
Id=7, Status=ACTIVE Data Root=D:\temp\test\equinox\org.eclipse.osgi\bundles\7\data
...
Here's what OSGI Core Release 8 specification says about bundle identifiers:
Bundle identifier - A long that is a Framework assigned unique
identifier for the full lifetime of a bundle, even if it is updated
or the Framework is restarted. Its purpose is to distinguish
bundles in a Framework. Bundle identifiers are assigned in
ascending order to bundles when they are installed. The method
getBundleId() returns a bundle's identifier.
So that at tells us two important properties about bundle identifiers: 1.) the relationship between bundleId and bundle is stable from the time that it is installed to the time that it is uninstalled, and 2.) that bundle identifiers are assign in ascending order to when they were installed.
Going back to the original question, trying to get bundles identifier number assignments to start over works against the OSGI specification for bundle identity, and you shouldn't mess around with trying to control bundle identity. For example, let's assume you have three bundles installed:
b1(0), b2(1), b3(2)
Now lets assume you uninstall bundle b2 (with id = 1):
b1(0),b3(2)
Now lets assume you re-install b2:
b1(0),b3(2),b2(3)
Notice that b2 gets a new id assigned to it. That id is stable for referencing b2 as long as b2 is not uninstalled. And if you notice, the id of 1 is no longer used. Bundle id is an identifier, not an index into an array. The bundleId of b3 can't be changed because it wasn't uninstalled, b2 could not be assigned the bundleId of 1, since that would violate the rule the bundle identifiers are assigned in ascending order to when they were installed (the OSGI framework doesn't remember that b2 was previously installed and uninstalled - it looks like its just being installed for the first time). Given that the bundleId is a long, that means we would need to do 9,223,372,036,854,775,807 bundle uninstalls before OSGI's bundle id number assignment scheme would run out of id's.
Related
In an OSGi-environment using Apache Felix file-install, one of the bundles does not work.
At first, the bundle does not appear at all; however I can install it manually. It becomes INSTALLED (not RESOLVED as it should):
osgi>install file:///path/to/my/bundle.jar
Bundle id is 230
osgi>diag 230
file:///[...]
No unresolved constraints
osgi>ss <filter>
id State Bundle
230 INSTALLED <bundle-name>
I can start the bundle with start 230, and everything works (services start). After stopping the bundle with stop 230, the bundle is RESOLVED; after update 230 however the bundle enters state INSTALLED again.
How can I identify the cause why the bundle is not RESOLVED automatically?
This is by design:
Installing a bundle will leave it in installed.
When you try to start a bundle, the resolver will first try to resolve it's dependencies, if it succeeds it will transition to resolved and from there to started.
When you stop a bundle, it will transition back to resolved (no need to un-resolve anything at this point as you might want to start it again).
When you update a resolved bundle, regardless of the fact if this is really a different version of the bundle or not, it will be seen as "new" and it will go to installed state.
So in short: updating a resolved bundle will leave the new version of it in installed state by design.
Bundle identifier does not have com. in my XCode project.
Why?
How can I fix it?
1. Why-
Normally XCode puts a nice bundle identifer. Maybe you don't have an account name to your mac or maybe while setting up your project you edited the bundle identfier.
2. How to fix-
Have a look at "Setting the Bundle ID" in this doc.
You can edit bundle identifier from-
My bundle identifier is com.nikhilmanapure.avfoundationexample.
Normal convention is web url in reversed manner and appending project name. This makes the bundle identifier unique. Your aim should be making bundle identifier unique, because that is needed when you upload app to AppStore.
I have no experience in patching/upgrading an installation.
We have a wix bundle setup with a standard (wix-created) msi inside which is added to the bundle this way:
<MsiPackage SourceFile="MySetup.msi" Id="MySetupId" Cache="yes" DisplayInternalUI="no" SuppressSignatureVerification ="yes" Visible="no" >
so in Add/Remove software section there is the bundle shown, not the msi itself.
Both, the msi and the bundle, are signed.
Currently our released version is "2.1.0.BuildNumber".
The bundle.wxs has upgrade code A
The msi has product code B and upgrade code C.
Unfortunately this version contains a mean bug but we don't want to release "v2.2.0.BuildNumber" just because of this bug, but "2.1.1.BuildNumber", so we need a patch.
What is be best practise here? Should we just create a msp file described like here
http://wixtoolset.org/documentation/manual/v3/patching/wix_patching.html?
Will this break the relationship between the bundle and the msi? Will this patch be shown in Add/Remove programms section?
Or is there a possibility to use the bundle for a patch?
Goal is, that our customers just can install the patch without deinstalling the old version, but can deinstall the whole scope using the formerly released bundle.
My personal advice is do not create patches unless absolutely necessary. You avoid a lot of trouble. The main problem IMO is that patches do not fit well onto source control and CI. First, you are not able to automatically increase the build number and include it into version number - it must remain the same. Second, creating an msp patch requires the binaries from the previous build be present during the new build. In MS technology the previous msi should be present, in WiX technology you cited you will need *.wixpdb from the previous build. Third (or the first?), the patch is a one-time action which should not be automated for continuous execution by CI.
If the bundle does not include its packages into exe but download them, a new bundle version can download only changed packages so that installation time will be small. Otherwise you are out of luck.
You need to create an msp upgrade for your buggy msi. The upgrade may or may not change the msi version, but if it does then the version of msi will not match the version of the bundle. User does not see msi version anyway.
You can install msp directly. When the bundle is uninstalled, msp will be uninstalled too. I do not know whether the msp will be visible in ARP (msi is not visible).
You may create a patch bundle. This is an independent bundle with its own upgrade code. It will contain
<Bundle .... ParentName="Name of your main bundle"...>
<RelatedBundle Id="YourMainBundleUpgradeCode" Action="Patch" />
Include MspPackage with your msp into the Chain.
This bundle will be visible in Installed Updates as a child of "Name of your main bundle" and it will be uninstalled with the main bundle or when a new version of the main bundle is installed.
You will also need to include a Condition to prevent installation of patch bundle when the main bundle of this particular version is not installed. There is no documented API to detect bundles (although you may use a RegistrySearch), but you may do ProductSearch for particular version of your msi included in main bundle.
Note that a new release of the main bundle with the same version number will install in parallel (there will be two identical entries in ARP) and new release with greater version number will automatically uninstall previous release. Thus, you cannot make new release of the main bundle.
I'm developing a ruby/rails application which should be highly extensible by adding plugins. A plugin is - obviously - a gem, which follows specific roules and contains library code, a rails engine with assets, routes, controllers, views and whatever. Additionally there wille be some kind of API which allows the plugin developer to register custom entries to abstract concepts of the app like adding cronjobs (theres some kind of cron in the main system), adding commands to the CLI and so on.
There will be some 'builtin' plugins containted in the Gemfile shipped with the app due they're part of the app and always activated. And there will be a pool of community written gems which are optional.
Now I'm searching for a possibility to let the user, who installs the app on his machine, addional gems (containing plugins) to the app.
The simplest (but not best) solution would be to say "Just add the plugin gems you want to the Gemfile before running bundle install)". But if there comes an update of the app, the Gemfile would be potentially conflicting and either be resetted or the user have to resolve those conflicts. That's something I don't want actually.
A nicer way would be to say "Hey, here's a UserGemfile, just add the plugin gems you want to that file and run bundle install". That UserGemfile would be listed in the .gitignore and everything would be nice.
Unfortunately it seems like bundler doesn't support something like that.
Do you have any advice how to tackle that issue?
You can do something like this, in, say, import_gems:
puts `cat Gemfile UserGemfile > EffectiveGemfile`
puts `bundle install --gemfile=EffectiveGemfile`
Then, when you run your application, specify the Gemfile:
BUNDLE_GEMFILE=EffectiveGemfile bundle list
Make sure to add EffectiveGemfile and EffectiveGemfile.lock to .gitignore as well.
Using Felix / Equinox, what do the following do under the hood?
osgi:install
osgi:refresh
osgi:resolve
osgi:restart
osgi:update
Is there a state-machine diagram or more concise documentation somewhere?
The best documentation for this is the OSGi Core Specification. The section and page numbers below refer to Release 4.3 (April 2011) of the spec.
osgi:install means install a bundle from a file or stream, and it maps to the BundleContext.installBundle method in the API. Refer to section 4.4.3 on page 90.
osgi:refresh performs a "refresh packages" operation, which allows exports/imports to be rewired after installing or updating a set of bundles. For example, bundles that are currently wired to a particular exporter of a package may be rewired to a newly installed bundle that exports the same package. See section 7.6.1, page 148.
osgi:resolve is similar to refresh, but it only wires up bundles that are currently in the INSTALLED state. I.e. it will not rewire existing wires belonging to bundles that are already in the RESOLVED sate.
osgi:restart stops and restarts a specific bundle. This does not cause the bundle implementation to be updated, it simply stops and starts. See section 4.4.5 page 91 and 4.4.7 page 95.
osgi:update requests for a single bundle to be updated (i.e. reloaded from its original location). This may involve stopping, re-resolving and starting the bundle, depending on what state it was in before the update. See section 4.4.9 page 95.
The state diagram for all the OSGi bundle states is in section 4.4.2 (Figure 4.4) page 90.
For the details of what the Felix shell commands do, you might just look at their source code, at http://svn.apache.org/repos/asf/felix/trunk/shell/src/main/java/org/apache/felix/shell/impl/ - most of them are short and simple.