-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manifest of pax-logging-logback has an Import-Package directive for org.slf4j version 1.7 instead of 2 #518
Comments
@ffays thanks for report, but please, tel me where do you see this Even today (for #516) I run all the integration tests and everything works fine.
So |
@grgrzybek Indeed I'm trying to load it into Karaf 4.4.3 using Equinox as OSGi runtime. Starting from a vanilla Karaf 4.4.3 (with
Leads to I find a bit odd that the |
@ffays Karaf 4.4.2 by itself uses pax-logging-api + pax-logging-log4j2. If you want Logback, you have to build your own custom Karaf distro using <feature version="${project.version}" description="Karaf core feature" name="framework-logback" hidden="true">
<!-- persistent wiring extension -->
<bundle start-level="1">mvn:org.apache.karaf.features/org.apache.karaf.features.extension/${project.version}</bundle>
<!-- mvn: url handlers -->
<bundle start-level="5">mvn:org.ops4j.pax.url/pax-url-aether/${pax.url.version}</bundle>
<!-- logging -->
<bundle start-level="8">mvn:org.ops4j.pax.logging/pax-logging-api/${pax.logging.version}</bundle>
<bundle start-level="8">mvn:org.ops4j.pax.logging/pax-logging-logback/${pax.logging.version}</bundle>
<!-- config admin -->
<bundle start-level="9">mvn:org.osgi/org.osgi.util.function/1.2.0</bundle>
<bundle start-level="9">mvn:org.osgi/org.osgi.util.promise/1.2.0</bundle>
<bundle start-level="9">mvn:org.apache.felix/org.apache.felix.coordinator/${felix.coordinator.version}</bundle>
<bundle start-level="9">mvn:org.apache.felix/org.apache.felix.converter/${felix.converter.version}</bundle>
<bundle start-level="10">mvn:org.apache.felix/org.apache.felix.configadmin/${felix.configadmin.version}</bundle>
<bundle start-level="11">mvn:org.apache.felix/org.apache.felix.configadmin.plugin.interpolation/${felix.configadmin.interpolation.plugin.version}</bundle>
<bundle start-level="11">mvn:org.apache.felix/org.apache.felix.cm.json/${felix.cm.json.version}</bundle>
<bundle start-level="11">mvn:org.apache.sling/org.apache.sling.commons.johnzon/${sling.commons.johnzon.version}</bundle>
<bundle start-level="11">mvn:org.apache.felix/org.apache.felix.configurator/${felix.configurator.version}</bundle>
<bundle start-level="11">mvn:org.apache.karaf.config/org.apache.karaf.config.core/${project.version}</bundle>
<!-- file install -->
<bundle start-level="12">mvn:org.apache.felix/org.apache.felix.fileinstall/${felix.fileinstall.version}</bundle>
<!-- features service -->
<bundle start-level="15">mvn:org.apache.karaf.features/org.apache.karaf.features.core/${project.version}</bundle>
</feature>
See https://github.com/ops4j/org.ops4j.pax.logging/blame/b7f13ea5b6ac5481da7e203cf3b532d3fdef0c6f/api/osgi.bundle - it was added in 2007 with this commit: 528cf5d ;) I agree - but that's how it works and that's the implementation detail chosen in the golden age of OSGi... |
@grgrzybek I've to admit I'm getting a bit lost ... as I'm initial intent is to have the "vanilla" java.util.logging (JUL) package to work within Karaf, and so far I have no success to have logging messages showing below the INFO level (i.e. FINEST, FINER and FINE are not showing), so I try to understand what to do with OPS4J Pax Logging to have lower level JUL messages going thru Karaf logging. Somewhat I'm glad that your are on this message thread, as you were in charge of the JUL Levels test for Logback (cf. commit d0e6626) Nowadays
However "Logback" is not part of the vanilla installation of Karaf, so I had the idea i've somewhat to deploy it to have access to this configuration ... maybe I'm wrong. The bottom line I would like to have JUL working and to see my development "FINE" log messages ... be welcomed to provide guidance/advice to have it working! PS. Regarding your comment: "I agree - but that's how it works and that's the implementation detail chosen in the golden age of OSGi..." |
@ffays I can understand the confusion. You have to remember few things about the internal, unavoidable and inherent structure of Pax Logging - there are two layers of logging here:
We used to have 3 implementations - Log4j1, Log4j2 and Logback, now we got rid of Log4j1.
And these are also APIs - even if they're also implementations:
And finally, Logback doesn't have any special API - it's recommended to be used behind SLF4J. Now, the main principle of Pax Logging was to allow many bundles/libraries, running within OSGi environment (like Karaf) to use any kind of logging API, while ALL the log methods should be directed to single logging implementation, configured using single configuration file. So, in my opinion the most popular API is SLF4J and I write my libraries/bundles to use this API. But in OSGi runtime, I want the logging to be performed by Log4j2. This is quite easy and common scenario. Outside of OSGi it's realized by:
But imagine this - a bundle is using Log4j1 API and you still want to have actual logging to be performed by Log4j2 - that's what Pax Logging is for. Same for Commons Logging, JBoss Logging etc. Check out this test: https://github.com/ops4j/org.ops4j.pax.logging/blob/main/pax-logging-it/src/test/java/org/ops4j/pax/logging/it/AllLoggingFacadesIntegrationTest.java: String name = "org.ops4j.pax.logging.it.test";
// 1. SLF4j
org.slf4j.LoggerFactory.getLogger(name).info("INFO using SLF4J");
// 2. Commons Logging
org.apache.commons.logging.LogFactory.getLog(name).info("INFO using Commons Logging");
// 3. JULI Logging
org.apache.juli.logging.LogFactory.getLog(name).info("INFO using Juli Logging");
// 4. Avalon Logging
org.ops4j.pax.logging.avalon.AvalonLogFactory.getLogger(name).info("INFO using Avalon Logging");
// 5. JBoss Logging
org.jboss.logging.Logger.getLogger(name).info("INFO using JBoss Logging");
// 6. Log4J1 API
org.apache.log4j.Logger.getLogger(name).info("INFO using Log4Jv1");
// 7. Logback - only behind SLF4J
// 8. Log4J2
// Log4J2 Logging involves log() methods that pass FQCN
org.apache.logging.log4j.LogManager.getLogger(name).info("INFO using Log4Jv2");
// 9. JUL - extra handling without a pax-logging specific facade and shadowing. Only handler redirection
java.util.logging.Logger.getLogger(name).info("INFO using java.util.logging");
java.util.logging.Logger.getLogger(name).fine("FINE using java.util.logging");
java.util.logging.Logger.getLogger(name).finer("FINER using java.util.logging");
java.util.logging.Logger.getLogger(name).finest("FINEST using java.util.logging"); All the above calls are handled by the same logging implementation! Now you have to realize the magic behind pax-logging-api bundle - indeed it exports org.slf4j.LoggerFactory.getLogger(name).info("INFO using SLF4J"); Uses:
classes not from real org.slf4j/slf4j-api jar/bundle, but from pax-logging-api. Why? Because Pax Logging API changes implementation of the facade, so the calls are redirected to underlying OSGi machinery (it's not only about loggers, but also about MDC for example). The same is for other facades - the facades should be kind of grabbed from real libraries, but implementation should delegate to OSGi (trackers, listeners, ...). In your case you used pax-logging-logback without pax-logging-api - but with org.slf4j/slf4j-api library. But this official library doesn't know much about which implementation to use, so it can do only what is done in flat-classpath scenario:
But in OSGi the discovery is more dynamic, so pax-logging-api version (for SLF4J 1.x) provided own implementation of And finally an explanation of your problem with java.util.logging - java.util.logging.Logger.addHandler(new org.ops4j.pax.logging.internal.JdkHandler()); So everything again can be handled by single chosen logging backend. Standard Karaf distro uses I hope this explains the philosophy behind Pax Logging. Welcome to the OSGi rabbit hole ;) |
@grgrzybek Thank you for your detailed explanation
1.1. To go further, since Oracle has put in place the modularization in Java 9, I'm concerned that this library publishes classes in package names belonging to another open source project.
I had already analyzed the code of org.ops4j.pax.logging.internal.Activator and indeed it resets the main LogManager and take over the root java.logger.util.Logger discarting so any configuration that could have been made via the "java.util.logging.config.file" system property unless the "org.ops4j.pax.logging.skipJUL=true" system property is defined. Still even if "org.ops4j.pax.logging.DefaultServiceLog.level=DEBUG" system property is defined, I cannot see log messages below INFO level for JUL. Configuring "etc/java.util.logging.properties" seems to be pointless as it does not solve JUL logging below INFO level issue. I finally figured out that changing "log4j2.rootLogger.level = DEBUG" in "etc/org.ops4j.pax.logging.cfg" allows me to see the messages below INFO level for the OSGi logger but not for the JUL logger ... my quest continue ... Note that I hear you having the Unit Test passing, and this is certainly a good thing, however my feedback here is about what I do experience in a real deployment environment, so lets say that my experiments with Karaf might lead to have to adjust the Unit Test accordingly!? So what am I missing so far to have JUL message below INFO level to show in the Karaf log file? I guess I should open a separate issue this second point it is not the main topic of this issue!? -/- My two cents: I would like to emphasize that logging must be a basic commodity for software developers (i.e. it should be simple to use and not be "rocket-sience" grade). |
I've opened two separate issues for the two later points: |
I'll answer to your concerns tomorrow. Now I can only say that #519 can't be done. OSGi is great in theory, but painful in practice - 99% of the Maven Central libraries are not OSGi-first and even if they have OSGi-compliant The point is that we want to use Maybe it's better visible with the promise of J2EE/JavaEE/JakartaEE. I've been working with EE since 2002 and while the promise is that you use API, while entire implementation comes from (back in 2002 quite expensive, >10000$ per CPU per year) the underlying application server, the reality check shows that it's simply not possible. With OSGi you're not only adding new layer of dependency management (besides Maven), you wire multiple packages, you deal with tens of Guava implementations differing by major version on each release (thus, according to Semantic Versioning, incompatible), you private package libraries which you don't want as bundles (felix.utils, commons-io, httpclient, ...), you do all the kinds of magic... So no - there's no way we remove ... More rants and explanations tomorrow ;) |
Echoing Grzegorz comments – logging is a fundamental capability that application servers must be able to make opinionated decisions in order to support running as many deployment types (and their dependencies) as possible. Karaf is top-of-class in that regard—thanks to pax-logging’s approach.
I wonder if the disconnect here is development vs runtime dependency management.
During development, your project may depend on slf4j-api (<scope>provided</scope>) or other back-end implementations (<scope>test -or- provided</scope>).
At deployment, the Karaf runtime provides the logging APIs and Impls, so there is no need to include logging jars in the deployment descriptor. Just like java.lang.String, or other “core” features. The runtime provides those to the deployment.
The practice of including logging jars in wars goes back to practical work-arounds to limitations that those containers (Websphere, Tomcat, etc) had and are not reflective of any true best practice.
My $0.02
…-Matt Pavlovich
From: Grzegorz Grzybek ***@***.***>
Date: Tuesday, March 28, 2023 at 11:38 AM
To: ops4j/org.ops4j.pax.logging ***@***.***>
Cc: Subscribed ***@***.***>
Subject: Re: [ops4j/org.ops4j.pax.logging] Manifest of pax-logging-logback has an Import-Package directive for org.slf4j version 1.7 instead of 2 (Issue #518)
I'll answer to your concerns tomorrow. Now I can only say that #519<#519> can't be done.
OSGi is great in theory, but painful in practice - 99% of the Maven Central libraries are not OSGi-first and even if they have OSGi-compliant META-INF/MANIFEST.MF it more like a contribution for other authors or just automatic benefit of using maven-bundle-plugin (which, when used with defaults, sometimes leads to weird artifacts).
The point is that we want to use org.slf4j package - true, that's the promise of OSGi. But we HAVE TO know where this package comes from - and that's the requirement of reality. As I said - pax-logging-api needs to take over org.slf4j package to provide the same interface with different implementation.
Maybe it's better visible with the promise of J2EE/JavaEE/JakartaEE. I've been working with EE since 2002 and while the promise is that you use API, while entire implementation comes from (back in 2002 quite expensive, >10000$ per CPU per year) the underlying application server, the reality check shows that it's simply not possible.
You HAVE to know whether you use Hibernate or EclipseLink as your JPA implementation. Same for JMS, JCA, JTA, ... The best separation comes with Servlet API, but still - you have to be aware where do you deploy your WARs to.
With OSGi you're not only adding new layer of dependency management (besides Maven), you wire mnultiple packages, you deal with tens of Guava implementations differing by major version on each release (thus, according to Semantic Versioning<https://semver.org/>, incompatible), you private package libraries which you don't want as bundles (felix.utils, commons-io, httpclient, ...), you do all the kinds of magic...
So no - there's no way we remove org.slf4j from pax-logging-api bundle. Same for other packages - would you risk your system installing pax-logging-api without org.apache.log4j (yes - Log4j1) package, hoping that official log4j/log4j artifact will work? (yes - it HAS OSGi headers). No way! ;) Have a look at how many different versions of the same packages are exported from pax-logging-api - this is explicit, careful, conscious decision of original Pax Logging authors (I'm only a janitor here ;).
...
More rants and explanations tomorrow ;)
—
Reply to this email directly, view it on GitHub<#518 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AAD5A57W7HYMVYSYHXGQNDLW6MHZDANCNFSM6AAAAAAWJL2AFE>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
You're right here. Even if it's only about the principles and not actually how it works. After switching from Logback 1.2 to 1.3 (which switches from SLF4J 1.7 to 2.0),
So we're explicitly stating that we want this package only from a provider with explicit
Don't make me start about Jigsaw / JPMS / Java modules ;) Did you deal with So no - "I believe such things should be addressed once and for all, and to no longer happen since Java 9 has been released." - JDK9 was released on 2017-09-21 (5.5 years ago) and I just see customers moving to JDK11 from JDK8. No way OSGi is going to rebuild itself around JPMS...
While
This property is used if you have only
True. See above.
I've show you how to configure level for JUL logger in #520. And about this configfile name? Again - this is OSGi in practice (opposite to OSGi shouted out from the Ivory Tower).
This file is taken by felix.fileinstall, PID (Persistent Identifier) is determined (skip the extension, result in
See #520.
Your assumption about simple usage is completely rational. However we're talking about OSGi and while I love this technology, it has the highest imaginable actual-difficulty to promised-difficulty ratio... <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency> Expecting actual library to be available at runtime - exactly as you do with Servlet API Jar - you don't put it into your WAR file! You're right - JUL was introduced with JDK 1.4, but it doesn't make it the final, ultimate and perfect logging solution ;) The popularity of Logback and Log4j2 which came after JUL suggests the opposite. You should note the discrepancy between Java/JavaEE promise ("you don't have to look at other solutions, stick on our APIs and you'll be fine") and actual situation (popularity of Spring Boot for example). I always preferred to use SLF4J API, because I can quickly "turn it off" by adding Having said all that, I don't want to close the discussion - feel free to express your concerns, but Pax Logging is what it is - you have to accept the decisions made by giants on whose shoulders I (simple janitor) stand. |
Thank your in-depth knowledge over OSGi and Jigsaw. I've to admit didn't knew the purpose of the It has been a very instructive discussion, thank you one more time, feel free to close this ticket. |
Thanks for inviting me out of my comfort zone - this discussion was very inspiring - my goal was to really admit you have good points, but with OSGi you have to be careful when transitioning from the ideal model to reality ;) |
I cloned the tagged version 2.2.2, i.e.
git clone --branch logging-2.2.2 https://github.com/ops4j/org.ops4j.pax.logging.git
I noticed that for the
pax-logging-logback
project has a dependency toslf4j-api
version2.0.6
Cf. parent
pom.xml
line 247 for<version.org.slf4j>2.0.6</version.org.slf4j>
declaration:Cf. parent
pom.xml
lines 799-803 forslf4j-api
dependency declaration.However in the
META-INF/MANIFEST.MF
of the packaged pax-logging-logback-2.2.2.jar has anImport-Package
directive for org.slf4j version 1.7 instead of 2Cf.
This lead to this Exception:
As
org.slf4j.spi.LoggingEventAware
class is not part of the latest version 1 (i.e. 1.7.36) of slf4j-api.Could you please fix the
Import-Package
directive to refer to requireversion="[2,3)"
?The text was updated successfully, but these errors were encountered: