Installing two bundles with the same file - osgi

I am using OSGI declarative Services.
In my java application, I launch Apache Felix, and install and start some bundles.
There are two bundles installed using the same file path. Once the bundle starts, it is supposed to display a 'Hello' message.
When I install and start the first bundle:
Bundle bundle1 = context.installBundle("file:C://Users//bundles//myBundle.jar");
bundle1.start();
This shows 'Hello' in the console.
However, when I install the second bundle (with the same file path as the first bundle)
Bundle bundle2= context.installBundle("file:C://Users//bundles//myBundle.jar");
bundle2.start();
I don't see any output. It means that the installation and/or the starting of the second bundle was ignored.
I need a way to install and start two different bundles with the same file path, and when I stop one of these bundles, the other should stay ACTIVE. How can I possibly achieve that? Thanks.
The use case I am thinking of: Let's say I have two users, and both would like to use the same feature (bundle). What if one of them decided to stop the bundle feature, and the other one would like to keep it?
Is there a better way to achieve that? Thanks.

Does the file content change in between installing two times? If not, then you cannot do this. Essentially you're trying to instantiate the bundle twice, and OSGi only allows each bundle to be installed once.
Actually you can have multiple versions of a bundle at the same time, but the pair of Bundle-SymbolicName and Bundle-Version must be unique within the framework.
Mapping user functionality to installed bundles is really not a good idea. Why should users care about the modules installed in your application?? Instead you want to make the functionality in the bundle support multiple users.

You can call the function
context.installBundle(location, inputStream)
and pass an InputStream to that function. In that case, you can specify two different locations (e.g. one that has some meaning but not a real location).
Your next problem will be if two bundles with the same SymbolicName and same version can cannot exist twice.
I cannot imagine a use-case where the same bundle should be installed twice. It might be the result of a bad concept.

There are two things you need to consider: The bundle location must be unique and the framework must be set to accept multiple bundles with the same bundle symbolic name. You should use bundleContext.install(location, inputStream)
to install the bundle. Maybe like this:
byte[] byteArray byteArray = IOUtils.toByteArray(new FileInputStream(new File(filePath);
Bundle bundle = bc.installBundle(jobID, new ByteArrayInputStream(byteArray));
And to enable the framework to accept multiple bundles with the same bundle symbolic name, you need to start the framework with the following option:
-Dorg.osgi.framework.bsnversion=multiple
Notice that the update command will still try to update the bundle from the given location, which in my case (jobID) was not a real file path. This was irrelevant for my use case, so I never bothered to solve it.

Related

how can I ignore certain directories when initializing sorbet?

The summary: As far as I can tell, when I run srb init, it requires every single file. Is there a way to disable or customize this behavior before the config is generated in sorbet/?
I run into some trouble with this since my team keeps gems in a non-standard location (it's a polyglot monorepo.) In particular, I'd like to tell Sorbet to ignore things in _build, db, and script—short of adding a typed: ignore to every file (apparently this won't work for us due to how gems are being set up) how can I make Sorbet ignore these?
(some background: we tried to adopt Sorbet's static checks when it first came out and could not because we use Rails and the tooling was not working well enough yet. We found the runtime checks really useful, however, and so we've been using those extensively. I've been re-evaluating the static side every couple of months, and have been consistently gotten stuck when trying to create the sorbet directory!)
I believe you can start by creating and modifying the config file accordingly and then running the whole process. You can acomplish this by running srb rbi config first, and then adding a line like --ignore=db/ to the newly created file at ./sorbet/config.
For multiple directories you can put one on each line:
--dir
.
--ignore=db/
--ignore=vendor/

How to make my code discover an embedded utility?

Continuing with this question.
I have a command line utility embedded in a framework. That utility is used by third parties to handle some processing. There is no way I can not use that utility.
My problem is, I don't know how to locate my utility on disk. It's bundled in a framework within my main app, but I am not sure how to get the right path.
Halp?
Provided you've set a proper bundle identifier (CFBundleIdentifier) entry for the Info.plist file of the .framework, you can use NSBundle's bundleWithIdentifier: method to obtain the bundle representing the framework, then use pathForResource:ofType: to get the path to the executable. Just make sure you give the framework a unique bundle identifier (different from your main app bundle's bundle identifier).
For example, say I have an app bundle CoolApp.app that has a CFBundleIdentifier of com.blah.CoolApp. It has a TextureKit.framework framework which is at CoolApp.app/Contents/Frameworks/TextureKit.framework, and has a CFBundleIdentifier of com.blah.TextureKit.framework. Inside the Resources folder of the TextureKit.framework is an executable named textureUtility. I could use the following code to get the full path to textureUtility:
NSString *path = [[NSBundle bundleWithIdentifier:#"com.blah.TextureKit.framework"]
pathForResource:#"textureUtility"
ofType:#""];

Multiple gems from same jRuby project

I am creating a jRuby gem at the moment and I may need to expose different commands (from the bin folder) to different type of users. Is that a good standard to create different gems for that, such as "_userX" or "_userY"? (And also the gem name may be different from the project name, which I know it's not a standard)
So I my need something like "mygem_for_admin_users" vs. "mygem_for_normal_users".
Cheers
It definitely works, and there are definitely people doing it (example: https://github.com/mongodb/mongo-ruby-driver).
This is obviously very subjective, but I personally feel that it's bad practice to have a gemspec that doesn't match the project name, or multiple gemspecs in a single project. Ultimately, if it's the cleanest solution to the problem, it's the cleanest solution, and you should go for it, but first consider other ways of going about it:
You could have one base gem and 2+ interface gems that expose different sets of commands from the base gem.
You could somehow identify the different classes of users from the library itself, making all the commands available, but some of them restricted unless the right user type is set
You could build everything into one command with many subcommands (like bundle or git) that does the same reasoning about user types
There may be more options.
TL;DR: It's not great practice, but people do it and nothing will catch on fire. Just make sure that there isn't an easy way to avoid it first.

Two executables in one bundle on MAC

Is it possible to have two executables each with its own plist to share the same bundle. Then depends on the way app is executed (parameters) to load the appropriate executable.
Imagine the case where we have a main application (executable with UI) and the mini application (shorter version of the main app also with its own UI) and then depend on the parameters user used for starting the application execute the appropriate executable in the same bundle.
Cheers
Not exactly, but you could achieve something similar.
You could have a master Application bundle, which figures out which version of the code to run, and then have multiple plug-in bundles (as resources of the application) which actually implement the different versions. Each plug-in bundle would have its own Info.plist / nib files / etc.
See the documentation for NSBundle for details of how to load bundles and run their code.
I think I understand you. You want to share a plist between two executables. Just refer to the same plist in each case: tutorial for single executable plist.
Don't know if it's possible. Honestly I doubt it because the plist information is also used to define the icon and so on, so you would confuse the Finder if this would be possible (which icon should it display?). However, I am not an expert in Bundles, at all.
I give you a workaround. Create a demultiplexing script that runs the proper executable according to your parameters, and then associate the script with the plist information.

TextMate: Adding to a bundle

There are a couple of bundles that I would like to add some functionality to. If I update the bundles via SVN will my additions/updates be replaced?
Generally, you should check out a bundle's repo in the global /Library/Application Support/TextMate/Bundles directory; then, if you make any changes, the changes will be stored in ~/Library/Application Support/TextMate/Bundles, and you can easily (a) undo changes, or (b) update bundles without conflict.
To be honest, I forget what happens if you check out bundles to ~/Library/Application Support/TextMate/Bundles instead; I think your own changes get mixed in with the bundle itself, which can create conflicts when updating.
Here's the idiot-proof way to to make sure you don't unintentionally overwrite your custom-edited version during a Bundle update:
Instead of editing an existing bundle, create a new one (bottom left-hand corner of the Bundle Editor, click on the "+" dropdown then click 'New Bundle') and give it a unique (but descriptive) name.
Then just copy+paste the snippets, macros, commands, etc. that you want to modify, from the original bundle, to new snippet/macro/command windows in the Bundle Editor and start editing.
You might want to give Bundles you create this way names that begin with your initials followed by the name of the bundle you modified, e.g., 'DY-python'.
But it's not the unique name that you rely on to keep them from being overwritten. Actually, TextMate recognizes these by the fact that the name doesn't match the name of any Bundle in the Repository, and so, behind the scenes, TM stores them in a location different from the other Bundles, e.g., ~/Users/dougmbp/Library/Application\ Support/TextMate/Bundles, for the user-modified ones, while the default location for TM Bundles updated from the repository is /Applications/TextMate/Contents/SharedSupport/Bundles/.
There is absolutely no discernible difference to the user in how these two types of Bundles behave--they are accessed, edited, and called just like the conventional Bundles. This way, your modifications will survive Bundle updates, TM version updates, and well as bad things (just make sure you add the path above to your list of back-up locations).
No but if you additions conflict with changes made in SVN you will need resolve those conflicts by comparing and editing the two versions.

Resources