Installing several bundles from one source
I'm using Apache Karaf as an OSGi container. Karaf have url wrapper which can install bundles directly from maven repository
> install mvn:com.farpost.billing/background-service/2.2-SNAPSHOT
Bundle ID: 139
All works just fine. But I want to start several bundles from given source. This make sense if new bundle occasionally broke production service and I want to rollback. With OSGi this is very straightforward
> list
[ 139] [Active ] [ ] [Started] [ 60] Billing background service (2.2-20100811-1232)
[ 140] [Resolved ] [ ] [ ] [ 60] Billing background service (2.2-20100809-1127)
> update 140
> list
[ 139] [Active ] [ ] [Started] [ 60] 开发者_高级运维Billing background service (2.2-20100811-1232)
[ 140] [Resolved ] [ ] [ ] [ 60] Billing background service (2.2-20100812-1354)
> start 140
> stop 139
> list
[ 139] [Resolved ] [ ] [ ] [ 60] Billing background service (2.2-20100811-1232)
[ 140] [Active ] [ ] [Started] [ 60] Billing background service (2.2-20100812-1354)
#################
# suppose we need to rollback here
#################
> start 139
> stop 140
The problem is I can not create several bundles from one source:
> install mvn:com.farpost.billing/background-service/2.2-SNAPSHOT
Bundle ID: 139
> install mvn:com.farpost.billing/background-service/2.2-SNAPSHOT
Bundle ID: 139
Second install
call doesn't do anything but returns already existed bundle id. So my question, is there any way to create several bundles from one source url?
You're running into the problem that you can not install more than one copy of a bundle with the same symbolic name and version.
Even if you could, there are side effects of having two different versions of the same bundle installed in the scenario you describe, because as long as a bundle is installed, it can be used to resolve packages from. In your scenario, that is probably not what you want, since you want to use either one or the other bundle, but not a mix.
In the end I would advise you to install just the bundle you want. If there are issues with it, roll back by uninstalling the faulty bundle and installing the older version. In case you want to automate the installation and update of (sets of) bundles, take a look at Apache ACE, a software provisioning framework for OSGi that will help you automate such scenarios (and manage OSGi systems in general).
It's possible to install several bundles at once by using a features file. Currently, we have a features file that defines about 6-7 bundles. On top of that, the file contains one feature that requires the other 6-7. By installing the "master" feature, Karaf installs all the following bundles at the same time. And if you want, you can have Karaf run these bundles on start-up.
In order to do this:
Create a features file. More can be found here: external source
Put that features file somewhere in your m2 directory.
Modify org.apache.karaf.features.cfg in the Karaf home directory. Add the mvn URL to the features file you just created to the "featuresRepositories" tag. Optionally, add the name of the feature to "featuresBoot" if you want it to load them on start-up.
After you start Karaf, you can type "features:install name_of_feature". This will start the feature and anything else the features needs as defined by the features file.
Then you can type list to verify all the required bundles are running. This has the drawback of needing to be updated if any bundles change, or new bundles are added.
Hope this helps.
EDIT: Just saw this post is a year old! Stackoverflow RSS feed put this at the top of my list !?!
+1's to Marcel & Tony, as a both correct.
A bundle in the RESOLVED state is activity exporting/importing packages (ACTIVE means any activation of services has been initiated and completed), and you should be using Karaf features. Currently we hand-roll our karaf-features file (see the PDF docs in the distribution download), as the v2.x plugin creates a separate feature for each dependency and is a bit quirky (I haven't tried trunk/v3 but it appears to be fixed)
What you're trying has two gotchas;
- The pax maven url handler command will recognise that the bundle is already installed and do nothing
- Even if it did then the 2nd bundle would fail as most likely the symbolic name would be identical to 1st
(Worst) Option 1:
If you're really desperate to specifically work around this, assuming your using the maven-bundle-plugin, add the buildnumber-maven-plugin and this to the bundle config:
<Bundle-SymbolicName>${project.artifactId} ${buildNumber}</Bundle-SymbolicName>
Then when you're installing the bundles use the explicit snapshot version (SNAPSHOT in a version name is conceptually just a repository soft-link to the latest timestamped version):
install mvn:com.farpost.billing/background-service/2.2-20100812-1354
With this option, as Marcel states, you could have other bundles package imports wired to the RESOLVED bundle while importing services from the ACTIVE bundle - so class mismatches will break you system.
(Less Bad) Option 2:
Slightly better (and with no changes to pom.xml):
- Note the exact timestamped version of the bundle
- Invoke the
refresh
command - To rollback, uninstall the bundle and install the previously noted version
With this option, as Tony states, you're managing all those bundles individually which is a pain and dangerous (what works with what? where's this written down?). Karaf features and the versions-maven-plugin plugin would be a much better solution
(Good) Option 3:
- Split your bundle in two; an API bundle and implementation bundle - that way switching out your implementation bundle (services and actual logic) wouldn't affect the package wiring just the service resolution
- Use the OSGi versioning scheme, it has reasonable synergy with maven versioning (see the semantic versioning pdf and Peter Kriens post on negative qualifiers). The scheme is MAJOR.MINOR.MICO.qualifier, where the micro numbers which add no new functionality other than bug fixes
- SNAPSHOTs should be used only for development not production as you're working with a untested, subject-to-change, moving target (where you do have to use snapshots lock them down to a version you've actually worked with by using the timestamped version (for 3rd party dependencies, that you must use the SNAPSHOT version, the versions-maven-plugin lock-snapshots goal can help here)
- Use Karaf features, it makes large suites of bundles much easier to manage (deploy you're entire stack with one command and similarly upgrade)
精彩评论