Require-Capability attribute not consistent

I am working on reproducible builds for Apache Tomcat. Tomcat uses Bnd, via Ant, to generate OSGi and JPMS metadata.

reproducible has been set to true but in one JAR I am seeing variation in the Require-Capability attribute from one build to the next.

The difference appears to be one of ordering. The two variations are:

Require-Capability: osgi.contract;osgi.contract=JavaServlet;filter:="(
 &(osgi.contract=JavaServlet)(version=5.0.0))",osgi.contract;osgi.cont
 ract=JavaEL;filter:="(&(osgi.contract=JavaEL)(version=4.0.0))",osgi.e
 e;filter:="(&(osgi.ee=JavaSE)(version=1.8))"

and

Require-Capability: osgi.contract;osgi.contract=JavaEL;filter:="(&(osg
 i.contract=JavaEL)(version=4.0.0))",osgi.contract;osgi.contract=JavaS
 ervlet;filter:="(&(osgi.contract=JavaServlet)(version=5.0.0))",osgi.e
 e;filter:="(&(osgi.ee=JavaSE)(version=1.8))"

I have been exploring this with a simple test case. I haven’t been able to reproduce it exactly, but I can reproduce it by switching between using <fileset dir="${basedir}" includes="*.jar" /> and explicit <apthelement .../> entries when setting the class path for Bnd. I’ve checked with <pathconvert ... /> and the resulting classpath is the same in both cases. I’m not exactly sure what is going on but it looks to be related to the order in which the JARs are processed by Bnd.

Is there some other Bnd configuration I should be using to avoid this or is this a bug in Bnd?

Thanks,

Mark

Perhaps Bnd is added the clauses in encounter order which may vary for different file systems.

So we would need to fix Bnd to do some sorting on the clauses .

In the interim, you could attempt to modify your build to make sure the classpath order is consistent. <fileset dir="${basedir}" includes="*.jar" /> is probably not reliable for this.

Thanks. I’ll see what I can do to refactor the Tomcat build to work around this. Do you want me to open an issue for the ordering of the Require-Capability clauses?

Yes, please. I suspect we may need to “normalize” the values of Provide-Capability also.

I you have a random order in your class path you’re bound to run into other differences. I think in a repeatable build it is crucial that you control the cp ordering.

There is more going on here than just class path ordering. If I log the class path I can see that the <fileset ... /> approach and the multiple <pathelement ... /> approach result in the same class path but different output. If I manipulate the class path ordering by changing the order of the <pathelement ... /> entries, the output does not change.

I’ll get that issue created.