2
votes

I've a jar(sample;version=A) needed by my OSGi application and i've to use the same jar(sample;version=B) to a newer bundle i develop.

The sample jar has some enhancements so i couldn't just upgrade the existing bundles to align to version=B.

I decided to add Sample with version B as a embedded dependency, so the newer bundle i develop refer to the latest version whereas the existing bundles runs with version A. Don't want to bring both the versions to run-time at the moment.

<Embed-Directory>lib</Embed-Directory>
<Bundle-ClassPath>.,lib</Bundle-ClassPath>
<Import-Package>*</Import-Package>
<Embed-Dependency>sample;scope=compile|runtime</Embed-Dependency>

At runtime only the older version of sample(version=A) is always referred. Is there a way the embedded-dependencies are made to refer by the bundles than taking from runtime exported packages?

Edit1: I also could see the packages present in sample are part of private-packages. Can the application made to refer to the private packages than referring to the runtime packages given by the OSGi container.

3

3 Answers

3
votes

Though this is an alternative in OSGI, it is a very bad practice to embed all the transitive dependencies into a mega bundle.

If the dependency is needed by only one bundle, then you can embed the dependency and it will be used with in the bundle. Otherwise wrapping it up as an OSGI bundle is the best option.

At times, we may have to manage with multiple versions of the same dependencies and in such cases, embedding the jar is the only option for you.

If you would like to embed different versions of the same dependency, then you should create a standalone bundle with no external dependencies (ie., Import-Package should be empty in your MANIFEST.MF).

If in case, if you have external dependencies and transitive dependencies as well, you have to properly exclude (negate) the packages from older version of dependency (version A in your case). Like below (as mentioned in @Christoph Läubrich answer),

<Import-Package>!com.test.*,*</Import-Package>

or import the missing/required dependencies alone instead of importing all external dependencies using (*) in Import-Package. Like,

<Import-Package>com.abc.*</Import-Package>

In the snippet of your pom.xml above, you are attempting to embed the dependency "sample" and trying to include all external dependencies which includes (your old version of sample). This is the reason why it is always referring to the older version of dependency though you have the required dependencies embedded in your bundle.

Reference: http://web.ist.utl.pt/ist162500/?p=1

2
votes

You must exclude the packages from your imports (e.g. !org.my.lib) then it will take them from the bundleclasspath only. At the momment you instruct to import every package needed and that includes your embedded ones too.

0
votes

I added dependency in bundle A.. if I use *;scope=compile|runtime in my pom, then the service which is using the depedency getting active, otherwise, it is going to Satisfied state.