Hello

I was thinking about one scenario. In my custom distro, I'm using pax-web
7.3.3 (tech preview
<https://groups.google.com/d/msg/ops4j/JP5L63Qh4u8/nPG1LN4HAAAJ>) which
uses Undertow 2, Tomcat 9 and Servlet API 4.

The "problem" is that maven-bundle-plugin, by default (and correctly)
generates import ranges according to pom dependencies. So if pom has
javax.servlet-api-3.1.0 dep, generated Import-Package header will have
(correctly) "[3.1,4.0)" range which is the most natural range according to
semantic versioning.

The problem is that with some deps (and servlet-api used in
"@org.osgi.annotation.versioning.ConsumerType" mode is such dependency)
you're safe to use newer version of the API.

There were different approaches to this problem, see for example:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=385806 where bundles either
export packages in many versions or export lower version than one matching
directly JavaEE specification. For example,
geronimo-servlet_3.0_spec-1.0.jar exports javax.servlet package with
version 2.6 and 3.0.

What I did (locally) is a little enhancement to new override&blacklisting
mechanism configured in etc/org.apache.karaf.features.xml. I added this
section for example:

<bundleProcessing>
    <bundle location="mvn:org.eclipse.jetty*/*">
        <add header="Processed-By" value="Karaf Bundle Processor" />
        <clause header="Import-Package" name="javax.servlet"
value='javax.servlet;version="[3.1.0,5)"' />
        <clause header="Import-Package" name="javax.servlet.annotation"
value='javax.servlet.annotation;version="[3.1.0,5)"' />
        <clause header="Import-Package" name="javax.servlet.descriptor"
value='javax.servlet.descriptor;version="[3.1.0,5)"' />
        <clause header="Import-Package" name="javax.servlet.http"
value='javax.servlet.http;version="[3.1.0,5)"' />
    </bundle>
</bundleProcessing>

My goal was to be able to install for example "camel-websocket" feature
which uses jetty which (at version 9.4) requires servlet API 3.1.

FeaturesProcessor (the one that currently can override URIs of bundles or
entire feature, blacklist features, bundle and repository URIs, has
(locally in my branch) ability to transform a bundle when matching some
criteria.

In the above example, I can override all jetty bundles, so each *individual
clause* (unlike with wrap: where you work at header level) can be changed.
I can add full headers, remove headers, modify headers or modify individual
clauses.

For example, to install jetty-util bundle, I had to wrap: it with:

wrap:mvn:org.eclipse.jetty/jetty-util/9.4.12.v20180830$overwrite=merge&amp;Import-Package=javax.imageio,javax.naming,javax.naming.ldap,javax.net.ssl,javax.security.auth.x500,javax.xml.parsers,org.slf4j.*;resolution:=optional;version=&quot;[1.7.25,2)&quot;,javax.servlet.*;version=&quot;[3.1,5)&quot;

remembering to preserve existing Import-Package clauses.

With XML configuration I can focus only on fixing javax.servlet.* import
clauses.

The transformed (repackaging + manifest change) bundles are stored in (by
default) ${karaf.data}/repository-bpr (bpr = bundle processing) directory,
which is also explicitly prepended to
org.ops4j.pax.url.mvn.defaultRepositories option used by maven resolver
used by features service.

Fitting into existing features processor mechanism, this change is actually
not that big. I see nice potential in it, but I'd very like to get your
opinion on it - maybe additional ideas? Or problems with current idea?

best regards
Grzegorz Grzybek

Reply via email to