Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does bnd add a uses directive for a package used only within a method body?

Tags:

gradle

osgi

bnd

I have a project with a single source file, listed here in its entirety:

package com.acme.el;

public class ExpressionUtils {
    public static Object evaluate() {
        new org.apache.commons.el.ExpressionEvaluatorImpl();
        return null;
    }
}

The functionality is irrelevant to the question. When I build the project as an OSGi bundle using Gradle, the manifest contains the following instruction:

Export-Package: com.acme.el;uses:="org.apache.commons.el";version="1.0"

What baffles me is that uses directive. As I've understood the directive, it is meant to define dependencies on other packages that need to be propagated to other bundles importing this exported package - if my class definitions or method signatures refer to classes in the org.apache.commons.el package, for instance. But in this class, the dependency on org.apache.commons.el is completely contained within the body of a method. It is not exposed in the API, and no other bundle importing com.acme.el could ever get a hold of the ExpressionEvaluatorImpl instance created in the method. So the dependency shouldn't need to be propagated, right?

Did I misunderstand the meaning of the uses directive, or is its use here unnecessary?

I made a minimal example GitHub repo for reproduction which you can clone and import as a Gradle project in Eclipse.

like image 342
Emil Lundberg Avatar asked Jul 02 '13 09:07

Emil Lundberg


2 Answers

If, in your bnd file, you set -experiments: true you should get the proper uses: clause, only based on public API references.

The problem is that bnd from the beginning has used all the imports to calculate the uses constraints. This was by far the easiest and nobody, so far, has ever complained about it. However, I did create the code to scan the public API but never felt confident enough to remove it from the experimental phase ... The current model is creating too many uses constraints but that should in general be the safe way.

This code has not been tested enough nor do I feel confident that changing this calculation will not create problems in existing builds. So I am in a bit of a bind here.

like image 157
Peter Kriens Avatar answered Sep 21 '22 08:09

Peter Kriens


Gradle 1.7 uses bnd 2.1.0, instead of bnd 1.50.0 which is used by earlier Gradle distributions. This problem does not occur when using Gradle 1.7, as demonstrated by this GitHub repo.

like image 27
Emil Lundberg Avatar answered Sep 20 '22 08:09

Emil Lundberg