Home > Java > After updating to 2.x, using 'slf4j.api' in an OSGi bundle requires the extension 'osgi.serviceloader.processor'

After updating to 2.x, using 'slf4j.api' in an OSGi bundle requires the extension 'osgi.serviceloader.processor'

王林
Release: 2024-02-10 21:12:08
forward
1149 people have browsed it

After introducing the latest update to version 2.x, the php editor Apple found that using "slf4j.api" in the OSGi package requires the extension "osgi.serviceloader.processor". This update is an important change for developers using this extension, as it provides more flexibility and convenience. The purpose of this update is to help developers better use and manage slf4j.api to improve program performance and stability. Developers can look forward to more updates and improvements to meet their evolving needs.

Question content

I created a small reproducer project on github: slf4j-experiment

Basically what I need is an osgi package with some code using slf4j-api.

Example:

import org.osgi.service.component.annotations.activate;
import org.osgi.service.component.annotations.component;
import org.osgi.service.component.annotations.deactivate;
import org.slf4j.logger;
import org.slf4j.loggerfactory;

@component(service = someservice.class)
public class someserviceimpl implements someservice {
    private static final logger log = loggerfactory.getlogger(someserviceimpl.class);

    @override
    public string doit(string first, string second) {
        log.info("someserviceimpl: doit(..)");
        return operation(first, second);
    }

    static string operation(string first, string second) {
        return first + second;
    }

    @activate
    public void activate() {
        log.info("someserviceimpl: activate");
    }

    @deactivate
    public void deactivate() {
        log.info("someserviceimpl: deactivate");
    }
}
Copy after login

In my build.gradle I have:

dependencies {
    compileonly 'org.osgi:osgi.annotation:7.0.0'
    compileonly 'org.osgi:org.osgi.service.component.annotations:1.3.0'

    implementation 'org.slf4j:slf4j-api:2.0.11'
    runtimeonly 'org.slf4j:slf4j-simple:2.0.11'
    
    // ...
}
Copy after login

This works as expected with slf4j 1.7.36

Now using the 2.0.11 version of slf4j, due to the use of service providers, there are new constraints modeled in the osgi metadata and now I'm stuck:

Resolution failed. Capabilities satisfying the following requirements could not be found:
    [<<INITIAL>>]
      ⇒ osgi.identity: (osgi.identity=slf4j.simple)
          ⇒ [slf4j.simple version=2.0.11]
              ⇒ osgi.wiring.package: (&(osgi.wiring.package=org.slf4j)(version>=2.0.0)(!(version>=3.0.0)))
                  ⇒ [slf4j.api version=2.0.11]
                      ⇒ osgi.extender: (&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))
Copy after login

Looks like I need an extra bundle, probably provided by spi fly, but I don't understand how...

Workaround

YourExample Statement:

slf4j.api;version='[1.7.36,1.7.37)',\
slf4j.simple;version='[1.7.36,1.7.37)'
Copy after login

(I'm not a fan of gradle osgi bnd) resolves to slf4j-api-1.7.36.jar from maven central.

This is the correct osgi bundle:

import-package: org.slf4j.impl;version=1.6.0
export-package: org.slf4j;version=1.7.36, org.slf4j.spi;version=1.7.36
 , org.slf4j.helpers;version=1.7.36, org.slf4j.event;version=1.7.36
Copy after login

But slf4j-api-2.0.11.jar has:

require-capability: osgi.extender;filter:="(&(osgi.extender=osgi.service
 loader.processor)(version>=1.0.0)(!(version>=2.0.0)))"
Copy after login

In fact - it satisfies aries spi-fly:

Provide-Capability: osgi.extender;osgi.extender="osgi.serviceloader.re
 gistrar";version:Version="1.0",osgi.extender;osgi.extender="osgi.serv
 iceloader.processor";version:Version="1.0";uses:="org.apache.aries.sp
 ifly"
Copy after login

slf4j got these headers (required) in this commit. p>

spi-fly is osgi's take on the java service loader, dynamically transforming the bundle's code so that the correct thread context classloader is set.

This is actually a proper requirement for slf4j api 2 as they switch from the static binding of the logger implementation to /meta-inf/services/ org's service discovery.slf4j.spi.slf4jserviceprovider service.

However, osgi is a tenacious beast. For logging, I recommend the pax logging project, which not only exports the correct org.slf4j package, but also allows you to dynamically configure the logging backend and configure it using osgi configuration management.

The above is the detailed content of After updating to 2.x, using 'slf4j.api' in an OSGi bundle requires the extension 'osgi.serviceloader.processor'. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template