Inconsistency between 'uses' and 'Import-Package' - eclipse-plugin

I am using bnd to generate MANIFEST.MF for a library. In the end, I get a Manifest with the folllowing conflict:
Export-Package: A;uses:="B,C"
Import-Package: B
Package A, B, C all reside in separate plugins, also named A, B, and C. At runtime, Eclipse does not load plugin C, and so I get a crash. Also, the Eclipse tooling appears to only look at Import-Package, because the tooling is also unaware of the dependency on C.
Should Import-Package always contain all of the packages in the uses statement? Is it an Eclipse bug, or (more likely) what am I doing wrong with bnd that's causing it to miss the dependency on C?

For your question:
Should Import-Package always contain all of the packages in the uses
statement? Is it an Eclipse bug, or (more likely) what am I doing
wrong with bnd that's causing it to miss the dependency on C?
The answer is: No.
With Importing you are declaring which packages your bundle needs, with exporting you declare which packages you give away to other bundles. The uses is a hint for the resolver that the Importing Bundle which needs package A will also need to import package B and C.
This makes it easier on the resolving mechanism to find the appropriate bundles. Especially since the bundle that exports A does also need to import B but not C.
Clarifying question:
It seems like Import-package ought to contain everything in uses, I'm
trying to understand a scenario where it wouldn't.
Bundle A is your bundle and exports package my.a.package
it uses package their.b.package from Bundle B and therefore Imports it.
This is the simple stuff here. Now since you export my.a.package bnd analyzes also Bundle B for you.
Since you aren't explicitly using any classes from Bundle C those aren't imported.
But since bnd analyzed Bundle B for you it knows that packages from Bundle C are used as transitive dependency in B.

Related

Dependencies between plugins

I wrote an app which uses plugins, everything is ok, I made my plugins with the bundle template of Xcode.
Now, I need to write a plugin that depends on another plugin, let's say plugin A depends on plugin B.
I tried to link plugin A with plugin B by adding it to the project (link binary with libraries) but that does not work (tried with the full bundle and with the plugin object file inside the bundle).
The only way I found for the moment is to add source files of plugin B to the plugin A but it is bad because in the application, both plugin A and B contains same code (Class X is implemented in both Y and Z. One of the two will be used. Which one is undefined).
How can I implement that ? Thank you
Ok, I found a way to achieve that.
Just copy or reference the header of the classes I need and then use the -U linker flag (in the Other Linker Flags option) in the following form :
-Wl,-U -Wl,_OBJC_CLASS_$_NameOfTheClass
(Wl option is needed, see here why : http://www.cocoabuilder.com/archive/xcode/264371-ld-undefined-symbols-argument-is-ignored.html )
The -U flag for a class allows to compile without having the definition of the class.
With that, I can compile the plugin without duplicating the code of plugin on which I depend.

Ivy cache not updated with a compiled and published module

Module A uses module B. I compile module B which implies a new jar in ~/.ivy2/local/[group]/B/[version]/B-[version].jar.
~/.ivy2/cache is not updated.
My problem is that Module A is trying to find B in ~/.ivy2/cache (that's what IvyDE indicates).
How can I ensure the cache is updated once project B is compiled?
Regards
You may want to use the workspace resolver feature of IvyDe:
This will makes all eclipse projectes directly available, without the need to build/publish th artfifacts.
Note: The Screenshot ist for 2.2.0Beta, but the feature exists for the current version, too.

Maven dependency

Hi i have a quite simple question about maven dependency. I have 2 modules of one project. So first module is dependent on second. Second module has dependencies on some libs. Second module can be itself installed as standalone app. So when i build the project the first war will contain packaged second module as well as all libs that second module depends on.
I need that when i package first module the second module should be included without it's dependencies. How it is possible to manage?
Thx
I need that when i package first module the second module should be included without it's dependencies. How it is possible to manage?
Somehow, this is an hint that the dependencies of the 2nd module are provided when it gets packaged inside the war. IOW, declaring the dependencies of the 2nd module with a provided scope would do it, they wouldn't get pulled transitively.
Depending on how you create the standalone distribution of the 2nd module, you might need to combine dependencies scope with profiles, or not. Can't say since you didn't say anything about this :)
References
Dependency Scope

OSGi unit testing without step that packages bundles

I have checked a few testing solution for OSGI including PAX and had a quick look at the abstract TestCase within Spring DM but they both appear to require one to jar up and bundle associated bundles. I was hoping to find something that works without this intermediate step.
Imagine the ability to package up packages on your classpath so that packages x and y made up bundle XY and packages x and z made up bundle XZ. Bundle XZ would not "see" package "y" but could import a service from XY living in package x. Any comments if this is possible or if a equivalent test case / library exists ?
I think that using Tiny Bundles from OPS4J with Pax Exam is what you are looking for.
http://wiki.ops4j.org/display/paxexam/ExamAndTinybundles
If you really want to enforce runtime visibility rules than you probably have to run your tests inside OSGi environment and pay some performance overhead.
However it might be sufficient for you to enforce compile time visibility by separating your classes into distinct compilation units (e.g. separate Maven modules X,Y,Z) with proper dependencies and then running a standard testing framework (e.g. JUnit) without OSGi.

Embedding JARs into the OSGi bundle with maven-bundle-plugin

I’m trying to embed some JARs into single OSGi bundle using the feature of maven-bundle-plugin
The thing that worries me is that all packages of embedded JARs are put into the Import-Package header of the generated MANIFEST.MF.
If I specify explicitly to use only the packages I need, like in the following snippet:
Import-Package: org.osgi.framework
The build fails with BND error (unresolved references).
So, the question here is how can I build the bundle with embedded JARs with "Import-Package" header I need?
All the packages that are imported in your classes will be imported by bnd. Perhaps you do not want those packages imported because you know that at runtime you won't be needing them. If you cannot stop bnd from importing them, you can make them optional so that your bundle will still resolve even if they are not supplied by another bundle (at wire time). Try to add this:
<Import-Package>*;resolution:=optional<Import-Package>
To your maven bnd configuration in maven.
One possible reason why you are seeing "unexpected" packages in Import-Package header is the following:
A general good practice that supports collaboration model in OSGi is to import all packages that you export -- see this blog post by Peter Kriens for detailed explanation why. Bnd (and hence also maven-bundle-plugin) follows this practice by default and automatically imports all exported packages. Therefore you should first check your Export-Package header and make sure that you export only the packages you want.
Also if you want to export packages from the embedded dependencies then you should be careful to avoid duplication inside your bundle -- see section Embed-Dependency and Export-Package of the maven-bundle-plugin documentation.
You should use Bundle-ClassPath if you want to make classes available inside a bundle that contains JARs e.g.
Bundle-ClassPath: foo.jar,other.jar
Import-Package: org.osgi.framework,org.other.imported
You'll need to list the classes that foo.jar and other.jar import/use, but you won't need to list any of the packages in foo.jar or other.jar unless you're actually exporting them.
You can remove some packages from import-package scope when you embed a JAR into your bundle:
<Import-Package>![package_name9]<Import-Package>
inside pom.xml or if you use external *.bnd files:
Import-Package: ![package_name]