ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas Beckmann <T.Beckm...@mwaysolutions.com>
Subject Experiences from using the OSGi OBR resolver
Date Mon, 04 Mar 2013 15:22:10 GMT
Dear all,


I am a software developer working on a solution based on the OSGi OBR resolver of Ivy 2.3
and would like to share my experiences in using the experimental implementation.

Bugs in Ivy:
1. The namespace transformation does not work properly when using the OBR resolver. The reason
is that the resolver does not provide an ivy descriptor artifact. As a result I get a NullPointerException
in NameSpaceHelper#transform(Artifact, NamespaceTransformer) because in line 67 (ModuleRevisionId
mrid = t.transform(artifact.getModuleRevisionId());) the reference artifact is null.
2. When a bundle exports the same package in multiple versions Ivy is capable of resolving
one version only. When trying to resolve the version not captured by Ivy, the bundle is found
but the version is not. This currently unsupported operation results in a NullPointerException
in AbstractOSGiResolver#findResource(ResolvedResource[], ResourceMDParser, ModuleRevisionId,
Date) at line 286 (Message.info("'" + osgiType + "' requirement " + mrid.getName() + ";version="
+ mrid.getRevision() + " satisfied by " + ((MDResolvedResource)found).getResolvedModuleRevision().getId().getName()
+ ";" + found.getRevision());) where in the case outlined the reference found is null. Although
the use case is unsupported it's probably good to fix the NPE.

Bugs in IvyDE:
3. At the time of writing the WorkspaceResolver does not correctly support overriding dependencies
using the <override>-tag in the <dependencies>-tag of an ivy.xml. I debugged it
and found that <overrides> are implented as mediaton rules (see DefaultModuleDescriptor#getAllDependencyDescriptorMediators()).
Now, in WorkspaceResolver#cloneMd(ModuleDescriptor, Artifact) a copy of the descriptor is
created. That copy lacks the mediators of the original descriptor. As a consequence, the <override>
rule does not apply when a dependency is resolved against the workspace.

Observed limitations of the approach that take some effort to fix:
4. In OSGi it is allowed to export the same package in multiple versions. In Ivy the package
versions are stored in an attribute _osgi_export_PACKAGENAME of the extra info of the module
descriptor. Since the attribute is not a collection but a single value, just one package version
can be kept per package. The code I'm talking about is in BundleInfoAdapter#toModuleDescriptor(ModuleDescriptorParser,
URI, BundleInfo, ExecutionEnvironmentProfileProvider) at line #96 (md.getExtraInfo().put("_osgi_export_"
+ exportPackage.getName(), exportPackage.getVersion().toString());). In principle, the implementation
could work with a collection and would do the right thing I think. At least I saw no apparent
reason why it should not work.
5. In OSGi a common technique is to do an Import-Package of a package exported using Export-Package
by the same bundle/module, to get a shared implementation when one is available or fall back
to the build-in one otherwise. This constellation results in an endless loop when constructing
the descriptors, which ultimately results in a StackOverflowError. When this happens the recursion
in DefaultDependencyDescriptor#addDependencyConfiguration(String, String) becomes a self-recursion
with the same parameters. Unfortunitely it's not that simple however because when package
uses are involved this cycle can spawn multiple modules. I think this cycle can be broken
and fixed by moving the manipulation of the confs map from the end to the method in the beginning
of the method.
6. Finally, the execution environments are implemented in the OSGiManifestParser. I looked
just briefly into it, but it appears to me that this is used when building the repository
index using buildobr (ivy/ant) only. It's used to define <exclude>s during processing.
This is a problem for me as I'm forced to write the index file in an entirely different way.
I don't think there is a way of encoding the execution environment in the index file yet,
so that Ivy would be using it. When using the famous BindEx tool one get the execution environments
as a requirement of a resource as like this: <require extend='false' filter='(|(ee=J2SE-1.5))'
multiple='false' name='ee' optional='false'>Execution Environment (|(ee=J2SE-1.5))</require>.
It would be nice if this could be supported by the OBRXMLParser#RequireHandler.

For me, I worked around most of the issues by running a quite complex XSLT over the repository
index file, eliminating self exports, missing exports and forcing versions 0 when the same
package is exported twice. The IvyDE bug can be worked around using a combination of <exclude>
and <dependency> instead of the <override>. Afterward Ivy and IvyDE are working
really nice! Keep up the good work!


Best regards,
    Thomas.


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message