I hope your are still reading to this mailing list because it has been
quiet for a long time now :)
As you may have seen, I have checked in a bunch of code into svn. This
is an experiment I did to make Ivy support resolving OSGi
dependencies. I did it whithout trying to support standard Ivy
repositories, but repositories that have already compiled in one file
what OSGi bundle they have in there. It is working quite well, I think
this is promising. Let me explain it in detail.
First we have a MANIFEST.MF that I want to translate into some Ivy
ModuleDescriptor. The mapping is based on few principle:
* no organisation, the OSGi symbolic name is the module name
* use of Ivy extra attribute to make the difference between a import
package and an require bundle:
<dependency osgi="pkg" name="javax.servet" rev="....
<dependency osgi="bundle" name="org.eclipse.core" rev="....
* the OSGi "use" on package export are expressed via some Ivy
configurations. For instance if I have:
Export-Package: org.bushel, org.bushel.servlet;use:=javax.servlet
Import-Package: org.apache.log4j, javax.servlet;resolution="optional"
Then in Ivy world:
<conf name="default" />
<conf name="optional" />
<conf name="use_org.bushel" extends="default" />
<conf name="use_org.bushel.servlet" extends="default" />
...
<dependency osgi="pkg" name="org.apache.log4j" conf="default-
>use_org.apache.log4j" />
<dependency osgi="pkg" name="javax.servlet"
conf="optional,use_org.bushel.servlet->default" />
So I think that with this mapping I didn't loose much info from the
manifest
And then we have an Ivy resolver, which already know what is in its
repository, via a repository.xml containing stuff like:
<repo>
<bundle name="org.bushel.testbundle" version="1.2.3"
uri="org.bushel.testbundle_1.2.3.jar">
<export name="org.bushel.testbundle" version="1.2.3" />
<import name="org.bushel.otherbundle.util" version="2.4.1" />
</bundle>
<bundle name="org.bushel.testbundle.importing" version="3.2.1"
uri="org.bushel.testbundle.importing_3.2.1.jar">
....
(note that I did not tried to support the OBR spec, too complicated
for this experiment, I just designed a dumb xml format)
So the resolve process is:
* first check what kind of dependency is required: osgi=pkg or
osgi=bundle
* get in the pre computed map the bundles which match the requirement
* select the best bundle of the filtered selection: for osgi=bundle,
it is just like in Ivy world, no worry. But for package, we have to
select a matching bundle, while several different ones can fit in.
If we want to build a classpath for compilation purpose, I think we
don't care of the chosen implementation, only the API is useful. So I
made the resolver configurable so it can take the first matching bundle.
And then about building runtime classpath, I think that even if we
declare some import-package (so the exact same bundle can be used in
another runtime environment), it is still good to specify which
implementation we want to use. So instead of trying to only rely on a
MANIFEST.MF (which would only declare dependencies on APIs), we would
want to have an ivy.xml that specify the implementation we want at
runtime.
An exemple:
MyProject with a manifest with:
Import-Package: org.springframework.web.servlet
and an ivy.xml with
<dependency name="org.mortbay.jetty" />
In the repo:
* org.springframework.web_2.5.4.jar with a manifest with:
Export-Package: org.springframework.web.servlet
Import-Package: javax.servlet
* org.mortbay.jetty_6.1.10.jar with a manifest with:
Export-Package: javax.servlet
* org.apache.tomat_5.5.jar with a manifest with:
Export-Package: javax.servlet
I think a such user story makes sense. WDYT ?
This last part has not been implemented: make Ivy support two
dependency descriptors, and make Ivy resolve the dependencies of the
ivy.xml prior to the manifest.mf.
Nicolas
PS: pfew, I might be verbose here, but I think the topic deserves it :)