[slf4j-dev] [JIRA] Updates for SLF4J-586: MANIFEST.MF exports a package with a former version number

slf4j developers list slf4j-dev at qos.ch
Thu Apr 27 13:13:00 CEST 2023


SLF4J / SLF4J-586 [Open]
MANIFEST.MF exports a package with a former version number

==============================

Here's what changed in this issue in the last few minutes.


There is 1 comment.


View or comment on issue using this link
https://jira.qos.ch/browse/SLF4J-586

==============================
 1 comment
------------------------------

Grzegorz Grzybek on 27/Apr/23 13:02

Joining late to the interesting discussion ;)

I've [added a comment under SLF4J-579|https://jira.qos.ch/browse/SLF4J-579?focusedId=21699&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-21699], but let me elaborate a bit more here.

[~frederic.fays], about the summary of this issue: "MANIFEST.MF exports a package with a former version number"

You're not 100% right assuming that it's something wrong. osgi.core-8.0.0.jar exports several (~20?) packages with versions starting with {{1.0}} and it's not a problem. While OSGi has a notion of "bundle version", what is important for the resolver (and recommended usage of {{Import-Package}} instead of {{Require-Bundle}}) is the package version(s).
{{org.slf4j}} package didn't change that much between version 1.7.x and 2.0.x, so from SemVer point of view, the major upgrade is not justified.

In practice we (developers) are so much used to bundle/library versions ({{<version>}} in Maven POMs) that it's _natural_ for use to translate this to package versions. This is nightmare for Guava users in OSGi...

>From OSGi point of view, SemVer has very important role and nothing in OSGi spec says that the bundle (library) version SHOULD (or even MAY) translate to package version. But the blame goes to bnd/maven-bundle-plugin which calculates package versions from Maven version (and generates {{[version, next-major)}}).

[~HannesWell]:
bq. Furthermore this allows much faster adoption of slf4j-2 in the OSGi world.

I'll never stop thinking about configured (in terms of installed bundles) OSGi runtime as _application server_. And for JavaEE, by "faster adoption of Servlet API 6" you don't mean "faster adoption of https://repo1.maven.org/maven2/jakarta/servlet/jakarta.servlet-api/6.0.0/jakarta.servlet-api-6.0.0.jar", but "faster adoption of application servers implementing Servlet API 6".

{{<provided>}} scope for Maven does exactly this - you should not treat {{<provided>}} deps as part of the deployment, but part of the contract (requirement) of your app. Same for slf4j-api JAR - if you create OSGi application, you don't assume you'll copy this JAR along with your application. You assume there'll be something provided at runtime. And that's how pax-logging-api satisfies the "provided" dependency to SLF4J API.

[~frederic.fays]:
bq. The worse: org.ops4j.pax.logging.pax-logging-api is exporting packages that are not even part of its project!

As discussed under https://github.com/ops4j/org.ops4j.pax.logging/issues/519 and https://github.com/ops4j/org.ops4j.pax.logging/issues/518 you should stop worry and accept this ;)

This practice is inherent for OSGi programming since it's dawn. If you look at https://github.com/apache/servicemix-bundles/ project, you'll find tons of bundles released to repackage other libraries under different groupId and artifactId to fix wrong or non-existing OSGi metadata.

Don't make me ask you to look inside https://repo1.maven.org/maven2/net/sf/ehcache/ehcache/2.10.9.2/ehcache-2.10.9.2.jar. Really - nothing to see there ;) Don't look.

{quote}
And for this issue, it is a project team choice as well.
For which I still believe such choice makes the troubleshooting harder...
{quote}

Yes. And no.

If you have CVE in Tomcat library from {{CATALINA_HOME/lib}}, what do you do? Change your application? Change the library in Tomcat? Patch the Tomcat? Replace the Tomcat?
It depends. At some point the size of your application server justifies replacement. At some point it's better to patch.

Real life example (from my field). Red Hat Fuse is based on Apache Karaf, which uses Pax Logging API + Pax Logging Log4j2. Pax Logging API repackages log4j1 (now reload4j) and 8 other Logging API facades.
During [Log4j2 apocalypse|https://www.lunasec.io/docs/blog/log4j-zero-day/] we had to "fix the problem". During few days starting from Dec 10th 2021, I've released about 20 different versions of pax-logging. I managed to do it alone. It was painful, it wasn't only a matter of deployment to Maven Central, we also had to prepare patches for Fuse/Karaf (using Fuse own patching mechanism). And what if the change was needed only in Log4j2? It wouldn't be much different...

So troubleshooting, maintenance and sustaining of the software is a complex subject. Assuming that bundles should export only own packages and only with versions matching the version of entire lib is simply unrealistic, though very appealing.

h4. Summarizing

[~HannesWell]
bq. But my naive first attempt would be, instead of shading/repacking the api classes from all supported facades into a own bundle, use the original (multiple) api bundles and provide a custom logging implementation/binding/provider that is wired to all the facades and does the redirection magic to whatever target or other logging-backend is intended. Basically just like all the other logging-backends and bridges work. But probably the pax-logging devs have considered that as well and had a reason to not do that.

Just as you rarely assemble your own JavaEE application server using API jars from https://repo1.maven.org/maven2/jakarta/ and own scripts, it's not common you assemble your own OSGi server.
Apache Karaf is one of the distros which does the plumbing for you and one of the built-in features is working logging subsystem. Pax Logging (just two bundles) gives you 9 Logging facades and Log4j2 (or Logback) backed configurable using OSGi Configuration Admin ({{org.ops4j.pax.logging}}) PID.

Now imagine you do it the _canonical_, pure way. You'd need:
* 9 API bundles (Log4j1 API, Log4j2 API, JBoss Logging API, Avalon Logging API, Knopflerfish Logging API, Tomcat JULI API, Apache Commons Logging API, OSGi Logging Service API, Pax Logging API (own API)).
* the _magic_ mentioned by [~HannesWell] to ensure that each of the above will properly, without deadlocks and memory leaks, preserving OSGi ClassLoading and package constraints _bind_ to single (you don't want logging performed by Log4j2 AND Logback at the same time, don't you?) logging implementation.

Do you know how to tell JBoss Logging to properly delegate to Log4j2 (JBoss Logging scans the CLASSPATH, without knowing it works in OSGi, were effectively you don't have CLASSPATH)? And do you know how to configure Logging levels in single configuration file, so Tomcat JULI API will obey the rules?
When you solve these problems, you'll eventually get to a solution similar to Pax Logging...

I'm only a Pax Logging janitor - the project was created by ninjas before me. But it taught me to look at the reality while knowing the ideals ;)


==============================
 This message was sent by Atlassian Jira (v9.6.0#960000-sha1:a3ee8af)



More information about the slf4j-dev mailing list